This post is from a thread in the "Macros" forum in which Rumble asked me some questions about my framework. I felt it more appropriate to answer them here so programmers wishing to bolster his framework can take my ideas and run with them if they wish:
I've been toying with the idea of avatars, where the players control a marker, but all the data is on a related lib token. But this could potentially be a lot of work.
That's sort of what I do in my framework. All player data stays on the "avatar", as you say, while all the player's powers stay on the Lib token. Of course, this arrangement is in keeping with the usual "Keep your code and data separate." paradigm. Yes, it did take a bit of work but was worth it in the end.
The result is a minimalist player token (approx 33% the size of a Rumble token) which acts as a client to the static "server" Lib. As soon as I did this, any lingering lag problems disappeared because the avatar was WAY smaller than the original amalgamated solution.
As for your "token name (backup)" idea, continually polling for token moves might prove expensive in terms of performance. Maybe a periodic findToken() call could serve the same purpose?
Interesting idea. I'm thinking you wouldn't need anything at all on the Avatar token except macros and a single property that names the corresponding Lib token. Do you have another lib token with the actual macros on it (so, for instance, your Avatar has a button called Attack. This button simply says
This hits a UDF on the Code Lib Token, which refers to the actual attack function, which refers to the proper lib token for getting and setting data, and then the Avatar is just updated?
Is that how it's structured? Or how do you structure it - that might be an interesting project to undertake (and also, I guess it means you can have multiple avatar tokens and it's not such a tragedy if you accidentally delete something!)
Think of this as a sort of "binary token" solution. Each player has two tokens, one to move around the battlefield (i.e. "Avatar", as you say) and the other which acts as a sort of golfer's caddy. This caddy (or "Code Lib", as you say) token is unique to each player. It contains the same power macros as yours except it calls my master framework token ("MyLibToken" in your example above). The Avatar calls it caddy any time it needs to run a daily, encounter, etc.
Yes I know you group your macros by action types and keep them all on a single token but you're right about my structure and process flow. There are barely any macros on the Avatar, usually less than 10 in fact. Each button calls one macro which displays a list of all macros it finds in the corresponding group on the Code Lib one.
For example, one of the buttons on the Avatar is called "At-Will". Pressing this calls the "Run Power" macro on MyLibToken. "Run Power" then looks at the Code Lib and finds the macro group called "At-Will" (because that's the label it read on the button). It gets the labels of all buttons in that group and presents this list to the user to choose from. It doesn't matter if there are 5, 25 or 100 buttons in that group. Although the menu may have 100 items in it, you still only need one "At-Will" button.
The "Code Lib" token can get quite large (up to 100K or so) but is never updated (no need since the Avatar holds all the data) so we don't need to worry about MapTool firing it around to multiple players. Because there is only a grand total of 10 lines of code on the Avatar (one "Run Power" call per button) and about 3 dozen properties, the resulting rptok can be as small as 10K. This is assuming the display JPEG is 2K and no portrait has been selected. Even with low network bandwidth and players in other cities, we've noticed MapTool has no trouble keeping up with token updates.
Keeping track of individual power macros can get tedious (because they're all uniquely coded) but the only other down side I can see to this approach is the need to continually cut and paste twice as many tokens to the next map. I will be looking into the "Teleport Pad" drop-in feature to solve this problem. Until then, it isn't that big a deal. Hopefully this clarifies.