The Aaron said: Just to clarify, Lua is a programming language, and just the way that Fantasy Grounds is customized. Doing something similar on Roll20 would be highly unlikely to use Lua. The main difficulty with FG rulesets is that it's not just skinning the thing. You're writing a large portion of the program's behavior as Lua events. Even opening dialogs is handled by Lua scripts in FG: -- /scripts/windowmanager.lua
function onInit()
Interface.onWindowOpened = onWindowOpened;
Interface.onWindowClosed = onWindowClosed;
end
function onWindowOpened(window)
local sourcename = "";
if window.getDatabaseNode() then
sourcename = window.getDatabaseNode().getNodeName();
end
if CampaignRegistry.windowpositions then
if CampaignRegistry.windowpositions[window.getClass()] then
if CampaignRegistry.windowpositions[window.getClass()][sourcename] then
local pos = CampaignRegistry.windowpositions[window.getClass()][sourcename];
window.setPosition(pos.x, pos.y);
window.setSize(pos.w, pos.h);
end
end
end
end
function onWindowClosed(window)
if not CampaignRegistry.windowpositions then
CampaignRegistry.windowpositions = {};
end
if not CampaignRegistry.windowpositions[window.getClass()] then
CampaignRegistry.windowpositions[window.getClass()] = {};
end
-- Get window data source node name
local sourcename = "";
if window.getDatabaseNode() then
sourcename = window.getDatabaseNode().getNodeName();
end
-- Get window positioning data
local x, y = window.getPosition();
local w, h = window.getSize();
-- Store positioning data
local pos = {};
pos.x = x;
pos.y = y;
pos.w = w;
pos.h = h;
CampaignRegistry.windowpositions[window.getClass()][sourcename] = pos;
end
Granted, some parts of the code (such as the above file) just get copied and shared for all of the rulesets, but that level of fine detail for what's required makes customization a bit of a pain. You've even got to layout things like the turn order window (the one for Exalted that I wrote is 305 lines of XML).