View Full Version : Modular Client Code
Tempered7
February 26th, 2025, 16:10
I was thinking about how modules conflict with each other or with the client sometimes and it downed on me:
As far as I understand, these conflicts stems from two different modules uses the same thingies in the code for different ways.
So, what if, the base code itself was modular just like in new user name rules in some online video games that adds a ID number to the words,
Like, if another person wanted to be "Tempered7" their system turns their user name into "Tempered7#1234" to differ from mine.
Can the same logic be used for separating different modules' references for the same thingies (I dunno, like, for reference to feats, etc) in the code?
Just a thought.
Ignore if it's too crazy :D
Trenloe
February 26th, 2025, 16:15
FG "modules" already have unique name references within the FG space. It's possible the display name may be the same, but the underlying FG reference will be unique. So I'm not sure exactly what you're looking at here. Can you please provide a specific example?
Or, by "module" are you actually referring to "extension""?
Either way, please provide an example.
Tempered7
February 26th, 2025, 16:21
FG "modules" already have unique name references within the FG space. It's possible the display name may be the same, but the underlying FG reference will be unique. So I'm not sure exactly what you're looking at here. Can you please provide a specific example?
Or, by "module" are you actually referring to "extension""?
Either way, please provide an example.
Ah, sorry. I was referencing to extensions and specifically the parts in their code that causes conflicts with other extensions & the client.
Without any knowledge in coding at all,
I thought maybe these conflicts can be prevented in the client by giving the conflicting code's reference point a different identity for each extension.
This way the client can run different codes that refers to the same ref point from each extension?
Again, it's just an experimental thought without knowing anything about coding.
So please ignore if it's stupid.
Trenloe
February 26th, 2025, 16:47
Interesting thought, but I don't think this will work. The base code isn't aware of what extensions can run and therefore can't control which extension code is ran, so there's not really a case of each extension having an identity. Extensions work by overriding the base code, with the last extension to load potentially overwriting base code and previously loaded extensions. With detailed knowledge of FG and how extension code can layer on other code, it's possible to produce an extension that minimizes the potential for clashes - but there'll still be that potential, and this won't necessarily cater for changes to the base ruleset code.
Tempered7
February 26th, 2025, 17:14
Oh, bummer. It was worth a shot though.
I checked some code thingies (parameters?) to redefine the solution in this possibility of extension to prevent crashes but it didn't produce anything useful.
Still though. It would be super practical if a conflict / crash preventing extension was possible.
Welp, sometimes new ideas just fall down to the bin. :D
Tempered7
February 26th, 2025, 17:20
Wait, how about an extension that finds conflicts in loaded extensions and gives their conflicting parameters new identities to separate them automatically and isolate them in 2 different zones to run them only when they're used?
LordEntrails
February 26th, 2025, 17:35
An extension could not do that. You would need an application that runs before FG actually starts to load the ruleset and then parse the ruleset code and all the selected extensions. And then it would have to know what to do, which would perhaps never be possible.
For instance, CoreRPG and 5E rulesets all have code that define or modify a window called "charsheet_item" (Which details the item/inventory page of the sheet). Now if you have two extensions that also modify this, say one to add a field to the inventory list such as Space and another changes the color of the fields. Depending upon how these extensions are coded, they might be resolvable, or they might not. (There are merge/join type of commands) But if both extensions fully overwrite the entire charsheet_item window class from the 5E version for example, then which one do you chose?
Renaming these window classes to something else would effectively break that part of the extension. For instance is one was renamed "charsheet_item-ext1" then FG simple wouldn't load it, because the other parts of the code don't call that, and can only call one window class for each window that is to be drawn.
Tempered7
February 26th, 2025, 17:51
An extension could not do that. You would need an application that runs before FG actually starts to load the ruleset and then parse the ruleset code and all the selected extensions. And then it would have to know what to do, which would perhaps never be possible.
For instance, CoreRPG and 5E rulesets all have code that define or modify a window called "charsheet_item" (Which details the item/inventory page of the sheet). Now if you have two extensions that also modify this, say one to add a field to the inventory list such as Space and another changes the color of the fields. Depending upon how these extensions are coded, they might be resolvable, or they might not. (There are merge/join type of commands) But if both extensions fully overwrite the entire charsheet_item window class from the 5E version for example, then which one do you chose?
Renaming these window classes to something else would effectively break that part of the extension. For instance is one was renamed "charsheet_item-ext1" then FG simple wouldn't load it, because the other parts of the code don't call that, and can only call one window class for each window that is to be drawn.
Oh food for the thought! Let me think.
An extension could not do that.
And then it would have to know what to do, which would perhaps never be possible.
If an extension can not do that, how about Unity itself? The client. It could also solve the problem of not knowing what to do because it can be something like error finder in the base code that runs before everything? I hope Unity can do such a thing. When I have time, I will check for more info about Unity Games.
As to what to do: It will just find a conflict, i.e: 2 extensions parameters that edit "charseet item-ext1", then it will give one of them a new parameter "charseet item-ext1-a" and the other one "charseet item-ext1-b" to separate them from each other. This is the base of the idea.
Depending upon how these extensions [ that changes "charsheet_item" ] are coded, they might be resolvable, or they might not. (There are merge/join type of commands)
That leads me to think about a system that's already in FGU. Legacy & 2024 D&D rulesets. If the whole ruleset can be modular for 2 different versions, then this might mean 2 different extensions that changes the same thing can also be separated into two versions. And for the player, it would take only 1 click to change the version. But I have to leave the "how" part to you coding-wizards. This also solves "then which one do you chose?" problem. A meme says, "Why not both?" :D
Renaming these window classes to something else would effectively break that part of the extension.
That's where the isolation part comes in handy. How about not renaming the code parameter within an extension but create a temporary or isolated copy of a new parameter based on the original code for the client to use the "copy" rather than the original code? Like in a Virtual Machine.
Tempered7
February 26th, 2025, 18:04
Hmm maybe unity crash handler can be utilized to find the errors?
Trenloe
February 26th, 2025, 18:05
The underlying thing to keep in mind is that extensions specifically overwrite, or add to, existing code. They are meant to "clash with" (i.e. change, overwrite or add to) existing code. Other than an error handler (which FG has - you need to know about errors) how will anything automated know if what the extension is trying to do is correct? You can't segment stuff off, because extensions are designed to overwrite or change that stuff into something different than the stuff that is segmented off.
Also, consider this: a lot of extensions are created by community members, a high proprtion of whom aren't experienced coders - either with LUA/XML or FG itself. They do enough to get the extension running and that's it - they probably won't feel inclined to create multiple versions or spend extra time (could be considerable time) to try to make them play nicer with other extensions and/or base rulesets. There's obviously exceptions to this, but a lot of the community devs I see on here want to create an extension to do what they want and move on.
LordEntrails
February 26th, 2025, 18:06
Part of the problem is that many existing extensions are not coded with the same best practices. Many don't use the merge/join commands either because they can't or (like me) the developer is not competent doing so. Any such resolution process requires that the extensions be developed with the same practices/methods/styles. And there is simple no way to achieve that today. Community Devs simple are not going to spend the time doing that. And then even some of the core code is not consistent because much of it is legacy. and it takes time away from development to clean up old stuff and bring it to current standards. And the motivation o do so it small when it's not broken and you are not working on that part of the code.
Someday AI applications will be advanced enough to do this and other code related things (like reliable take a large code base and convert it all to one standard). But that is at least many years off, if not decades. I'm learning AI tools, but am nowhere near proficient enough to reliably predict when they would achieve this capability. (And then they would have to be widespread and inexpensive enough for FG to adopt them.)
Tempered7
February 26th, 2025, 18:20
The underlying thing to keep in mind is that extensions specifically overwrite, or add to, existing code. They are meant to "clash with" (i.e. change, overwrite or add to) existing code.
This is the biggest problem, hmm.
Other than an error handler (which FG has - you need to know about errors) how will anything automated know if what the extension is trying to do is correct? You can't segment stuff off, because extensions are designed to overwrite or change that stuff into something different than the stuff that is segmented off.
Bold part is the question. Maybe if FG error handler tells what exactly causes the crashes (i.e: code parts), the new part of the client's "Modularization Code" (made up the name) can get its data from them. But what I originally thought as a method was to client to read a code in 2 extensions that tries to change the same parameter. Like using a ctrl+f in a text reader. Maybe this was where I hit the rock.
But, even with 2 extensions adding the same parameter that changes "charsheet_item" could the new code include a "search function" of these specific parameters? Maybe from the error logs, maybe with a code searcher mode, or something like that.
Also, consider this: a lot of extensions are created by community members, a high proprtion of whom aren't experienced coders - either with LUA/XML or FG itself. They do enough to get the extension running and that's it - they probably won't feel inclined to create multiple versions or spend extra time (could be considerable time) to try to make them play nicer with other extensions and/or base rulesets. There's obviously exceptions to this, but a lot of the community devs I see on here want to create an extension to do what they want and move on.
Extension creator will not be the ones who separate their extensions because it will not be the 2 version of the same extension. What I thought was 2 isolated code snippets that causes errors in 2 different extensions are being modularized to prevent crashes. And the Legacy vs 2024 ruleset code might help in doing that.
So only the new code error search function will be automatized as I described above. Hope this helps and you guys can find a way to prevent error before they happen :)
Tempered7
February 26th, 2025, 18:24
Part of the problem is that many existing extensions are not coded with the same best practices. Many don't use the merge/join commands either because they can't or (like me) the developer is not competent doing so. Any such resolution process requires that the extensions be developed with the same practices/methods/styles. And there is simple no way to achieve that today. Community Devs simple are not going to spend the time doing that. And then even some of the core code is not consistent because much of it is legacy. and it takes time away from development to clean up old stuff and bring it to current standards. And the motivation o do so it small when it's not broken and you are not working on that part of the code.
This is the biggest problem that blows my solution up. No standard coding in various extensions. And no solution for that.
Someday AI applications will be advanced enough to do this and other code related things (like reliable take a large code base and convert it all to one standard). But that is at least many years off, if not decades. I'm learning AI tools, but am nowhere near proficient enough to reliably predict when they would achieve this capability. (And then they would have to be widespread and inexpensive enough for FG to adopt them.)
Yeah. Maybe one day AI helps.
Well, it was at least a nice brainstorming.
Trenloe
February 26th, 2025, 18:39
Bold part is the question. Maybe if FG error handler tells what exactly causes the crashes (i.e: code parts), the new part of the client's "Modularization Code" (made up the name) can get its data from them. But what I originally thought as a method was to client to read a code in 2 extensions that tries to change the same parameter. Like using a ctrl+f in a text reader. Maybe this was where I hit the rock.
As mentioned - how do you know what's right and what's wrong?
So only the new code error search function will be automatized as I described above. Hope this helps and you guys can find a way to prevent error before they happen :)
What's an error? A clash in code? Maybe the clash is intended by the developer?
Other than an actual code error, which FG already has an error handler and let's you know about errors - as errors need to be fixed. I'm not sure how errors can be prevented before they happen - errors can be bad code, other extensions clashing, bad data, local computer environment and more. I can't see modularizing code as being a fix for all of this - because the error may be occurring in the base code, so there's nothing to package off and ignore.
It's an interesting idea, but I just don't see how this is going to work in the FG environment where, as mentioned, some code is specifically written to "clash" with other code.
Tempered7
February 26th, 2025, 18:42
Yeah, Trenloe. It seemed like a good idea as I was in a creative rush with too many chocolates and too much coffee :D
I thought defining the error as "two code snippets that changes the same parameter" would suffice but it is too shallow.
Welp, I'm not a coder lol. Wish I had some background in this, then I would be more helpful.
Trenloe
February 26th, 2025, 18:49
I thought defining the error as "two code snippets that changes the same parameter" would suffice but it is too shallow.
Like I've said - extension devs may be specifically changing that parameter - so it's not a case of tracking "clashes", because "clashes" may not be errors, and in most cases won't be. And extension developers can define the "loadorder" of their extension (https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996645556/properties) to specifically load after other extensions to allow their code to overwrite earlier loaded extensions, so they can have some control over how their extensions work - which is another tool an FG dev may use to determine how their extension interacts with other extensions.
Tempered7
February 26th, 2025, 18:56
Like I've said - extension devs may be specifically changing that parameter - so it's not a case of tracking "clashes", because "clashes" may not be errors, and in most cases won't be. And extension developers can define the "loadorder" of their extension (https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996645556/properties) to specifically load after other extensions to allow their code to overwrite earlier loaded extensions, so they can have some control over how their extensions work - which is another tool an FG dev may use to determine how their extension interacts with other extensions.
Man, I so wanna start learning coding for FGU now. If it can't be done maybe I won't even start it but maybe if I learn some info I can produce new ideas for you coding-wizards and you decide if it's useful or not.
Could you direct me to the very beginner stuff like a list of things that are used in FGU extensions to code?
Like xml, or other coding stuff.
Trenloe
February 26th, 2025, 19:08
You can start here: https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644285/Developer+Guide
Tempered7
February 26th, 2025, 19:11
You can start here: https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644285/Developer+Guide
Thank you. :) I'm on it.
Hope I can make something useful out of it.
LordEntrails
February 26th, 2025, 19:51
I started with a very simple extension, to replace the background decal. That's now base functionality, but was about as simple as you can get.
Have a goal in mind, like adding or removing a tab from a character sheet or item sheet or NPC. Maybe you would enjoy adding an NPC Item/Inventory tab?
Some other simple ideas, add a new field/attribute to something. You can use the Sanity/Honor extension as an example (though no idea if the code there uses best practices.)
Or create a theme like changing background colors or icons.
But whatever it is, start simple.
Tempered7
February 26th, 2025, 20:10
I started with a very simple extension, to replace the background decal. That's now base functionality, but was about as simple as you can get.
Have a goal in mind, like adding or removing a tab from a character sheet or item sheet or NPC. Maybe you would enjoy adding an NPC Item/Inventory tab?
Some other simple ideas, add a new field/attribute to something. You can use the Sanity/Honor extension as an example (though no idea if the code there uses best practices.)
Or create a theme like changing background colors or icons.
But whatever it is, start simple.
Oh, man! Using this dev knowledge to make Solo Play QoLs for FGU!
Hmm, Background Decal. Maybe I should start with it too, and turn it into a Solo QoL picture or something.
Thank you! I can't give you +rep because froum says I must spread rep myself but here it is: +REP :)
/Oprah Mode on
You get a +rep, Trenloe gets a +rep, Everyone gets a +ReEeEeEeEp!
LordEntrails
February 26th, 2025, 20:13
Decal is now a built in function from the assets preview window.
Automation is hard, because it requires scripting logic. Adding or changing fields on the user interface is relatively easy.
Tempered7
February 26th, 2025, 20:16
Decal is now a built in function from the assets preview window.
Automation is hard, because it requires scripting logic. Adding or changing fields on the user interface is relatively easy.
Ah, ok. Thanks for the tip. I assume it's the Lua Scripting that the dev guide refers to.
I remember its name from the OG Baldur's Gate times as the Infinity Engine used it iirc. But I never used it.
Trenloe
February 26th, 2025, 21:05
@Tempered7 - let us know how you go and if you have any questions.
The forums, rather than private messaging, is absolutely the best way to discuss topics like this.
Tempered7
February 26th, 2025, 21:12
@Tempered7 - let us know how you go and if you have any questions.
The forums, rather than private messaging, is absolutely the best way to discuss topics like this.
Sure.
I'm at the "Extension Data Files" part and trying to absorb the basics.
I thought about first learning the basics of rulesets, as extensions are created almost like them but it's getting late now.
I'll probably have many questions after I start learning XML as it seems the core of making an extension.
Thanks for all the help, you guys are being appreciated :)
Tempered7
July 1st, 2025, 22:35
@Tempered7 - let us know how you go and if you have any questions.
The forums, rather than private messaging, is absolutely the best way to discuss topics like this.
Sorry for necroing this thread but I don't know how to ask what I wanna ask right now:
- What is the general term for things like "string", "windowreference", "token", etc?
- What exactly all these parts of a module used for? I mean generally.
- And is there a page that lists all of them in one place?
My purpose is to make a test to see if I can realize vague ideas I have.
Like making complex story templates, custom mechanics, and so on.
All these will be in prep to learn to code Solo QoL extensions.
All these based on my assumption that these are the thingies that are used in creation of module parts somehow.
So learning about them might give me more ideas in aid to my current project (Random dungeon gen).
I tried checking Jeff's Excruciatingly Simple Extension Tutorial (https://www.fantasygrounds.com/forums/showthread.php?25234-Jeff-s-Excruciatingly-Simple-Extension-Tutorial) but the PDFs were gone.
Thanks in advance.
LordEntrails
July 1st, 2025, 23:28
Sorry for necroing this thread but I don't know how to ask what I wanna ask right now:
- What is the general term for things like "string", "windowreference", "token", etc?
- What exactly all these parts of a module used for? I mean generally.
- And is there a page that lists all of them in one place?
My purpose is to make a test to see if I can realize vague ideas I have.
Like making complex story templates, custom mechanics, and so on.
All these will be in prep to learn to code Solo QoL extensions.
All these based on my assumption that these are the thingies that are used in creation of module parts somehow.
So learning about them might give me more ideas in aid to my current project (Random dungeon gen).
Thanks in advance.
A "string" is a type of variable. Basically its a piece of text as opposed to a number. It might be a PC name, an item description etc.
A "window" is one of the visual elements that group things together for common display. Such as a charactersheet, and object window, etc. A "windowreference" is a reference to an a specific window. i.e. a reference between the combat tracker wounds for an PC to the wounds attribute on the charactersheet.
See the Developer Guide here for specifics: Developer Guide - Fantasy Grounds Customer Portal - Fantasy Grounds (https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644285/Developer+Guide)
Tempered7
July 1st, 2025, 23:34
Diggin' in right now. Thanks!
EDIT: More questions will be here.
Module Data Files (https://fantasygroundsunity.atlassian.net/wiki/spaces/FGCP/pages/996644362/Module+-+Data+Files) found them in here. These are not even like organs, but "cells" of a module. So all a coder do is to arrange them in relation to each other with references to the data types that do certain tasks. (don't mind me, just trying to define the process).
EDIT 2: Oh, so there are two databases. One for GM and the other for client (player). Which is what Trenloe was mentioning in the PF2 update. I think for solo QoLs I won't need to edit any client.xml files for Solo player plays in GM client.
Tokens
A token is a global built in package that provides global interfaces to token specific activities.Only tokens which are placed into token containers are handled by these functions. Image controls are currently the only valid token container objects.
So, tokens are only for image controls which are used to display large images stored in the database.
Tempered7
July 1st, 2025, 23:55
I edited post above.
Q1: Which data types should I start to learn if I want to create a complex story template? The kind that can handle both text and image gen (prompter cards). This is if Q2 wouldnt work.
Q2: Also, is it possible to use these data types to make edits to fundamental parts of a ruleset to change it to look like One Page SOlo Engine (https://img.itch.zone/aW1hZ2UvODIxMjUwLzU0MDgzNjkucG5n/original/KJGD%2BE.png)? Not the exact thing though.
So basicaly, a window looks just like the 1 page solo engine but with different parts;
1) Rules for a solo card game (standard deck) that will require Decked Out (https://forge.fantasygrounds.com/shop/items/910/view) by Saagael and Basic Card Decks using FG Tables (https://forge.fantasygrounds.com/shop/items/97/view) by Trenloe.
2) In combination with various parts from my guide; such as using the main methodology to set a first scene to ending it with a cliffhanger.
Trenloe
July 2nd, 2025, 00:22
Oh, so there are two databases. One for GM and the other for client (player). Which is what Trenloe was mentioning in the PF2 update.
There's only one database - with the GM having access to everything, and the players only having access to something that been shared or something they own (e.g. their PC). A single database is what is leading to the issue I mentioned in the PF2 update - if a player and GM access a PC sheet and change data in that sheet then it's stored in the same place in the FG database and both users (GM and owning player) will see the changes.
There's also the modules which each decides which one they want to open - with the GM allowing or denying access to specific modules. If the module stores data in a client.xml file then this is usually designed for player access and will default to being allowed to be activated by a player, if the module stores data in a db.xml file then that defaults to GM activation only.
Tempered7
July 2nd, 2025, 00:31
There's only one database - with the GM having access to everything, and the players only having access to something that been shared or something they own (e.g. their PC).
There's also the modules which each decides which one they want to open - with the GM allowing or denying access to specific modules. If the module stores data in a client.xml file then this is usually designed for player access and will default to being allowed to be activated by a player, if the module stores data in a db.xml file then that defaults to GM activation only.
Then 1 db won't be a problem in what I want to do;
The extension (with 4 column solo engine (https://img.itch.zone/aW1hZ2UvODIxMjUwLzU0MDgzNjkucG5n/original/KJGD%2BE.png)-like window) and module db will not change anything in below extensions but require them to guide the player to play a solo card game based on my guide.
EDIT: References to below modules will only be in text form in 4 column window. i.e: queen of hearts = unknown help / 4 color pack = encounter w/ loot, etc.
The window will contain;
1) Rules (text & d6 tables) that will require Decked Out (https://forge.fantasygrounds.com/shop/items/910/view) (includes the deck) by Saagael and Basic Card Decks using FG Tables (https://forge.fantasygrounds.com/shop/items/97/view) by Trenloe.
2) In combination with various parts from my guide simplified in prompters (aka drawn cards). "Rules" part will provide the meanings / usage of them. It can even be a co-op game.
If copyright is an issue, the module will only say you'll need these 2 extensions. no links, no references in code, or anything like that. The rule references will be directly to the standard 52 cards deck. d6 tables will be simplified modifiers for the rules. All will fit in 4 columns.
Q3: Anyone knows what happened to PDFs of Jeff's Excruciatingly Simple Extension Tutorial (https://www.fantasygrounds.com/forums/showthread.php?25234-Jeff-s-Excruciatingly-Simple-Extension-Tutorial)?
Q4: Or can anyone direct me to right place to learn the full structure of a module db / ext file; I mean in written code form.
Q5: And to interrelations in between data types to write the actual code? Or should I extract and connect that info from various wiki pages?
Where to start writing the actual code?
Nylanfs
July 2nd, 2025, 12:21
Do note, that there's a lot of discussion in the Workshop were a lot of new coder answers would help you fill in the blanks. :)
Mephisto
July 2nd, 2025, 17:19
You can also ask ChatGPT, it is fairly competent with FGU meanwhile. Just make sure you mention FGU in your prompt.
Tempered7
July 2nd, 2025, 22:38
Do note, that there's a lot of discussion in the Workshop were a lot of new coder answers would help you fill in the blanks. :)
I'll start start the search there. If I can find some sort of example code for a 4 column window, I think I can go from there.
You can also ask ChatGPT, it is fairly competent with FGU meanwhile. Just make sure you mention FGU in your prompt.
Oh, I didn't know that. I'll try that too.
Thank you all :)
Powered by vBulletin® Version 4.2.1 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.