PDA

View Full Version : Help with Extension Multiple RuleSet Support



Minty23185Fresh
April 16th, 2019, 15:50
I am trying to support multiple rulesets with one of my extensions. I've looked at the various documentation available and searched the forums but I can't find what I need.

The issue I am currently observing boils down to, some windowclasses having different names in the rulesets.
For example, a windowclass might have this definition in one ruleset:
<windowclass name="char_skill">

But the corresponding windowclass in another ruleset might have a this definition:
<windowclass name="charsheet_skills">

If I use the merge="join" parameter in my extension's windowclass override a fatal error is thrown when the xml parser comes across my extension's windowclass for which there is no ruleset definition to "merge" to.

What I need to do is be able to conditionally <includefile…> by ruleset. If the user is playing with the 3.5E ruleset the extension.xml file would include files only appropriate to that ruleset, and ignore those <includefile> definitions for other supported rulesets.

I know other developers must have run across this issue. Having a different .ext file for each supported ruleset is not really very palatable :mad: !

LordEntrails
April 16th, 2019, 18:22
I have no idea, but I know Dulux does it with his DOE extensions. Until someone pops in with more info, I suggest you look at DOE Base and another one (perhaps DOE Locations) to see how he has handled this in the past.

Trenloe
April 16th, 2019, 18:38
I have no idea, but I know Dulux does it with his DOE extensions. Until someone pops in with more info, I suggest you look at DOE Base and another one (perhaps DOE Locations) to see how he has handled this in the past.
The DOE's use new windowclasses - as they add new windows (sounds, locations, alignment graph, etc.).

@Minty23185Fresh - I don't think you can do what you want. The FG mechanism of controlling what extension functionality is loaded is provided by selecting the extension you want to load.

Minty23185Fresh
April 17th, 2019, 01:51
I suggest you look at DOE Base and another one (perhaps DOE Locations) to see how he has handled this in the past.


The DOE's use new windowclasses - as they add new windows (sounds, locations, alignment graph, etc.).

@Minty23185Fresh - I don't think you can do what you want. The FG mechanism of controlling what extension functionality is loaded is provided by selecting the extension you want to load.

Thank you LordEntrails, as Trenloe points out and somewhat as I expected with dulux oz’s epoch DOE extension set I believe he adds functionality. I on the other hand am trying to change functionality in multiple rulesets in similarly behaving code that has different naming conventions.

In the past I have been fortunate enough to be able to support multiple rulesets because I was able to override code in the CoreRPG ruleset (Field Filters and Local Dice Tower Extensions). The other rulesets inherited the functionality and so it worked in them too.

With the new functionality I am trying to add to my LDTE I’m not so fortunate. The functionality I am trying to override does not exist in the CoreRPG, but does exist in 3.5E/PFRPG and in 5E but in windowclasses with different names. As Trenloe points out there does not appear to be a way to direct the code parser to load different extension code based on ruleset.

I still have one avenue to explore: maybe I can embed my changes wholly within the templates employed by the windowclasses. I think one can have “vestigial” templates: defined code that is never used. I would put my code in a template that overrides the 3.5E template and in a template that overrides the 5E code. Then load both in my extension. If the 5E ruleset is loaded the 5E template would be overridden by my 5E extension template and my 3.5E template would just be “vestigial”. Visa versa if the 3.5E ruleset is loaded.

Minty23185Fresh
April 17th, 2019, 19:45
...I still have one avenue to explore: maybe I can embed my changes wholly within the templates...
This is possibly a solution, it looks like it might work, but at what cost?

One thing I abhor is excess copied code (it bloats the project and increases maintenance difficulty). I avoid copying ruleset code whenever possible. Because of templates, nested within templates, nested within templates, I would have to have copies of all those nested templates in my extension so that all the references resolve. To me this is pretty much unacceptable.

I find it more agreeable to try to maintain separate extensions (by ruleset) than have all that copied code to maintain. Bah!

Grifron
April 18th, 2019, 00:45
I am new to Fantasy Grounds, but if you are calling your code from within an existing window can you use 'self.getClass()' to get the name of the windowclass? Otherwise, can you dynamically build your xml file that you want to include with the current ruleset information passed in to it. I'm pretty certain you could make a Lua script that builds a xml file. That way in your code you would just need to have the name of the xml file that the Lua script builds dynamically and have the Lua script run onInit. I don't know for certain as I said I'm new to FG but that is how I would do it in VB.net.

Minty23185Fresh
April 18th, 2019, 06:13
Grifron, interesting, outside-the-box idea. I like it.
I don’t believe one could build an XML file and have it work. To the best of my knowledge there is no real file I/O capability other that writing to the db.xml and that is accomplished through the internal DB routines. Not through actualfile I/O. And, all XML is preparsed at start up, effectively eliminating the possibility of late binding. So even if you could write it I don’t believe you could get it parsed and interpreted.
However, all that aside, one could dynamically build the character sheet based on the ruleset. Populating a skeletal windowclass with controls. One might have to start with controls from the CoreRPG templates and layer properties and supporting lua script until you had the desired windowclass construct.
I might attempt this with something simple like say the 5e spell editor or weapon editor dialogs, but not with the character sheet.
As with the other solution(s) I’ve considered, I think the work and code necessary to effect this is far beyond the efforts I want to expend. I’ll go with maintaining separate extensions for the rulesets.
Thanks for your insight. It made me rethink the solutions available to me.

Grifron
April 18th, 2019, 14:59
What about this? You could add something like the below code to your .lua file that you include. You would just have to figure out which control sets the Merge or create your own function for setting the Merge in the windowcontrol.

function setMergeByRuleset(control) --I don't know which control can set the merge
local rset = User.getRulesetName()
if rset = "5E" then
--set the merge here for 5E
control.setMerge("join") --you might have to create this function yourself
elseif rset = "4E" then
--set the merge here for 4E
--no merge maybe, so no code
else
--no code for unknown ruleset
end
end

EDIT: Here is the other way I was talking about. Don't know if this will work, I did not test it. The escape characters probably need to be changed. But this could probably just be added to your .lua file.

function writeToFile(filename,contents)
local fh = assert(io.open(filename, "wb"))
fh:write(contents)
fh:flush()
fh:close()
end

function buildWindowClass()
local contents = "<?xml version="/""1.0"/"" encoding="/""iso-8859-1"/""?><windowclass name="/""test"/""></windowclass> <root> </root>"
local rset = User.getRulesetName()

if rset = "5E" then
contents = "<?xml version="/""1.0"/"" encoding="/""iso-8859-1"/""?><windowclass name="/""5Etest"/""></windowclass> <root> </root>"
elseif rset = "4E"
contents = "<?xml version="/""1.0"/"" encoding="/""iso-8859-1"/""?><windowclass name="/""4Etest"/""></windowclass> <root> </root>"
end
writeToFile("xml/testxml.xml",contents)

end

Trenloe
April 18th, 2019, 15:39
1) All the FG GUI files are loaded when the ruleset is loaded (first step of loading the campaign) - this applies for base windowclass etc. definitions and any merging in layered rulesets or extensions.
2) FG XML files (GUI, windows, controls, templates, etc.) are static, you can't generate them through code in FG.

The only options at runtime that you have in LUA are to create controls in a windowclass (each time the windowinstance is initialized): https://www.fantasygrounds.com/refdoc/windowinstance.xcp#createControl

Or change (with various set commands) or destroy (remove) an already present control: https://www.fantasygrounds.com/refdoc/windowcontrol.xcp

@Minty23185Fresh as you say, an approach like this will mean much more work as there'll need to be very specific LUA code for some rulesets, which will need to be manually worked out/created by reviewing the XML. Much, much more work to create and maintain than creating multiple extensions.

dulux-oz
April 19th, 2019, 04:13
Actually, I think you may be dismissing the DOEs in your solution-search too quickly - yes, the DOEs do add new functionality/windows, but I too ran into the "duel name problem" Minty is grappling with - and solved it (obviously).

I beleive you'll find what you're looking for when you consider the DOE:Location's "shop" function, in particular where certain Rulesets don't actually use money (the Numer... Ruleset, for example). You'll also see something similar around the Savage World Ruleset and the DOE:Locations's shopping function as well, where the "Equipment" pages of SW are actually 4 differnet page definitions (with different names), and so I had to be able to differentiate between them depending upon the End-User's actions.

Cheers

Minty23185Fresh
April 19th, 2019, 05:02
Thank you Trenloe for elaborating. I obviously wasn’t expressing my point well enough. I truly needed an interpreter to help me out. :)

And thank you dulux-oz for setting me straight. Your suite is large enough that I did not want to “tear right in” not knowing if the information I was delving for was in there.

I’m ready to release two ruleset based versions tomorrow (3.5E/PF and 5E). I suspect I’ll never seek the single .ext solution. Certainly not until more users request that I support more rulesets than these two/three. And now that it appears Unity is finally imminent, my little extension will become moot before it ever has 100 users.

Thanks again gentlemen.

Minty23185Fresh
April 19th, 2019, 05:11
@Grifron
It appears to me as though you’re assuming full lua language availability in your code examples. This is not true in FG. The complete language is not available to us; only a finite subset of it.

bmos
March 23rd, 2021, 13:09
Sorry to bump an old thread, but I have a solution to this which is very poorly documented. I actually have not seen it covered anywhere.
includefile has a parameter for this!

<includefile ruleset="CoreRPG" source="campaign/record_char_inventory.xml" />
<includefile ruleset="5E" source="campaign/record_char_inventory5E.xml" />
I haven't tried it with <script>, but it might work there also.

If not, you can always use the approach Grifron posted:


local rset = User.getRulesetName()
if rset = "5E" then
--set the merge here for 5E
elseif rset = "4E" then
--set the merge here for 4E
end

MostTornBrain
March 9th, 2022, 03:15
Sorry to bump an old thread, but I have a solution to this which is very poorly documented. I actually have not seen it covered anywhere.
includefile has a parameter for this!

<includefile ruleset="CoreRPG" source="campaign/record_char_inventory.xml" />
<includefile ruleset="5E" source="campaign/record_char_inventory5E.xml" />


Bumping an old thread yet again. :-)

I have to ask, how the heck did you figure this out bmos? Very poorly documented, indeed! After seeing your post, I did a google search for 'fantasy grounds "includefile ruleset"' and this post is the only thing google returns, and that's searching the whole internet!

Well, regardless, I'm quite happy you took the time to bump this old thread last year with your solution. It works very well and is exactly what I needed.

Cheers,
Brian

Moon Wizard
March 9th, 2022, 05:06
Actually, any asset (icon/die/windowclass/template/etc) as well as includefile can be marked with the ruleset attribute in extensions. @bmos probably picked it up when I've mentioned it a few times here and there. It's a relatively new feature, so I only have told a few people about it because of timing as well as making sure it works like we want.

Regards,
JPG

bmos
March 9th, 2022, 13:43
Actually, any asset (icon/die/windowclass/template/etc) as well as includefile can be marked with the ruleset attribute in extensions. @bmos probably picked it up when I've mentioned it a few times here and there. It's a relatively new feature, so I only have told a few people about it because of timing as well as making sure it works like we want.

Regards,
JPGSo far my experience with it is very positive. Having a single EXT handle xml for multiple rulesets is a neat trick :)
Very cool to know that I can use this on windowclasses and other assets!! This will let me prune down the code for some of my stuff quite a bit.
It would be very cool to also have something like ruleset~="5E" to exclude specific rulesets from a general file.

MostTornBrain
March 9th, 2022, 14:23
So far my experience with it is very positive. Having a single EXT handle xml for multiple rulesets is a neat trick :)
Very cool to know that I can use this on windowclasses and other assets!! This will let me prune down the code for some of my stuff quite a bit.
It would be very cool to also have something like ruleset~="5E" to exclude specific rulesets from a general file.

This is indeed a very cool and helpful feature. Can “ruleset” be a list or does one need to apply only one ruleset per entry? Currently, when I need the same xml for multiple rulesets I just list the same line with a separate ruleset - easy enough, but a list of rulesets would be handy. Also handy would be the “not” operation bmos mentions.

Thanks again for this feature Moon Wizard!

Cheers,
Brian

Moon Wizard
March 9th, 2022, 15:39
You can use ruleset="5E|4E|3.5E|PFRPG" to specify an asset used with multiple rulesets.

If you need ~=5E, then you can define a general one, and then override with a ruleset=5E one in the same file. It will just overwrite the general one.

Regards,
JPG

Minty23185Fresh
March 28th, 2022, 21:18
Thank you very much, bmos, MostTornBrain and Moon Wizard, for bumping and commenting on this old thread.

Your posts were instrumental in setting me on the proper path so that I could avoid having to use multiple extension files because of the desperate code/script that was needed to support each ruleset.