RPTools / maptool

Virtual Tabletop for playing roleplaying games with remote players or face to face.
http://rptools.net
GNU Affero General Public License v3.0
797 stars 260 forks source link

Macros to get/set/update/delete campaign properties. #2962

Open melek opened 3 years ago

melek commented 3 years ago

Is your feature request related to a problem? Please describe. Drop-in libraries and framework installation/upgrading sometimes require users to add states, bars, sights/lights, and properties to their campaign properties.

Currently we can get/view campaign properties with a variety of functions, but we still need the Create, Update, and Delete functionality to really make a true drop-in library that doesn't take the user work to set up.

Describe the solution you'd like I want a suite of functions that let us get and update token properties in a consistent, simple way. Specifically I want to be able to update:

Campaign Property       | Getter            
Token Props         | Partial * 
Token Props (Names)     | getAllPropertyNames()
Token Props (Names **)      | getLibPropertyNames()
Token Props (Types)     | Not available **
Lights              | !getInfo("campaign")
Sight               | !getInfo("campaign")
Bars                | !getInfo("campaign")
Bars (Image)            | getBarImage() 
States              | Partial *     
States (Groups + Name)      | !getInfo("campaign")
States (Image)          | getStateImage()

! Part of JSON output.
* Only some data available via macros.
** May include names not in the campaign.
*** Can be partially surmised via Macros.

Granular functions are okay - but if a function close to getInfo("campaign") was implemented as getCampaignProps, maybe a unified function like setCampaignProps which accepts a highly structured JSON to add/update (and a way to delete) properties could provide a super simple interface for this feature.

Describe alternatives you've considered

Additional context There are a great number of requests related to this. Here is

@cwisniew also has filed a suite of issues which might impact this request:

cwisniew commented 3 years ago

One of the bigger stumbling blocks I see how to resolve the situation where more than one library wants to set the properties. If they are dependant on the properties they set up to work correctly, then none of them may function correctly. Merging conflicts is going to be far from trivial and even getting the merge 100% successful could still lead to errors in the macros.

melek commented 3 years ago

One of the bigger stumbling blocks I see how to resolve the situation where more than one library wants to set the properties. If they are dependant on the properties they set up to work correctly, then none of them may function correctly. Merging conflicts is going to be far from trivial and even getting the merge 100% successful could still lead to errors in the macros.

I agree, there is a lot of room to create conflicts.

I have a few ideas that might work. One of them is to keep all macro-defined campaign properties separate from user defined properties, where the user definitions always take precedence.

Instead of overwriting each other, macro-defined properties could be given a priority number. Property declarations with the same priority wouldn't be guaranteed to be executed in a specific order, but you could set a different priority to coordinate with other add-ons you want to be compatible with. Not perfect, but it is one way to make it possible to both customize the properties for a campaign (with the user set properties) and integrate with other libraries more dynamically.

A non-destructive approach actually sounds pretty attractive - but maybe there are some other ideas out there in how to design something like this for success.

bubblobill commented 3 years ago

vaguely related getInfo("token"), setInfo("token") #2306 Same principle, the power to break things comes with the power to do awesome stuff.

melek commented 2 years ago

I wanted to iterate this feature request a bit with a solution I think would be great for add-ons.

What if campaign properties could be defined at runtime in a cascading way, where the user-defined properties are the base, then new properties can be defined on top of those? Conflicts are still possible at runtime, but it won't ever mutate the user defined properties.

Instead of a 'priority' system to try to fenagle conflicts, it would simply be that the last definition of a term wins out.

I'd love feedback on this approach - I think it might be a less destructive way of doing things.

Edit: One odd case here is 'Deleting' a property. I think that defining a campaign property with no settings, {} or similar, might be the equivalent of saying "Treat this as though it doesn't exist" - alternatively, it could be that you can redefine but never "delete" (unset) a property definition at runtime.

Azhrei commented 2 years ago

The order that add-ons are added would be a problem. How can you resolve that? Any priority system that you create would still allow for conflicts, and there would be no way to know what other authors have done such that you could pick a proper priority for your own add-on. And it may be possible that you could want yours to be before add-on A and after add-on B, but only for some properties?!

melek commented 2 years ago

Just like onTokenMove requires compatibility troubleshooting, so would augmenting campaign properties.

An alternative, likely better, is a namespaced campaign property system where an addon can only interact with its own and the user-defined properties, and those properties could be edited per-addon. Campaign Properties connected with an add-on could be accessible or private, like macros.

Tdue21 commented 10 months ago

I have to add that this functionality would be almost priceless to an add-on based campaign framework. By enabling creating and updating campaign properties, like token types, lighting etc. an add-on author can have everything contained within the add-on, instead of having to maintain mtprops files etc.

At the very least, it would be incredible helpful to be able to import campaign properties from a json file, instead of having to use a mtprops file.