Lib Properties and Campaign life

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
eRaz0r
Cave Troll
Posts: 41
Joined: Sun Mar 28, 2010 12:29 am

Lib Properties and Campaign life

Post by eRaz0r »

Ok, so I had this idea.
In a different thread (which I can't seem to locate this moment), I discovered that large, deeply nested JSON objects attached to active tokens (such as player tokens), tends to slow things down.
Conversely, using several properties to store data, on Lib tokens is faster. Accessing via getProperty is thus preferred.

So I was thinking of using a lib token as a data store, and then using a property named by each tokens name to store various random properties that don't need to be attached to the tokens themselves, such as the Conditions (dazed, blind, etc) that may be afflicting said tokens.

However, this is likely to be a bad idea, because it seems there's no real way to *remove* a property. You can set it to "", set it to default, and check if it's "empty", but there doesn't seem to be any way to remove a property, even it doesn't appear in the campaign properties sheet. So over the lifetime of a campaign, this lib:Datastore token is going to end up with a bunch of floating empty properties like "creature 93":"" that will never be cleared away. That's just not going to work.

So this leaves me with a nested JSON object again. Hmm.

Is there something I'm missing?

User avatar
CoveredInFish
Demigod
Posts: 3104
Joined: Mon Jun 29, 2009 10:37 am
Location: Germany
Contact:

Re: Lib Properties and Campaign life

Post by CoveredInFish »

You can store all your data in hidden properties on the token itself. Or is there a reason for placing them on a single libtoken?

The speed issue you mention is large & complex json structure versus single properties.

Since a token (a libtoken as well) with a huge amount of data has to be sent to each client after every change this could be performance critical in itself.

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Lib Properties and Campaign life

Post by aliasmask »

Actually, you can clear a property from a token with Wiki: resetProperty() and it will be deleted (see very bottom of wiki page). I've done some db experimenting with lib tokens and found that json objects (not arrays) seem to be the culprit of get/set slow down. Having more complex object/arrays slows get times (plus you have to dig for your target variable) and having too many properties dramatically slows down your set times (ie 600 properties takes about 2 seconds to set even a simple value) but the get time is about 4ms. As a rule of thumb, each operation takes about 1ms, so looping through 1000 lines of code takes about 1 second of operation time.

Another time consumer which bogs down everything is having too many macros on a token (say about 100+). I think this has something to do with having to draw buttons when selected. So, it is my experience that the fastest way to get and set values is to have many properties spread across several lib tokens and to keep the property objects as simple as possible (only 1 large 1 dim object with simple values or 1 large array with very small objects (1 or 2 key values).

Another problem is property get/set overhead. There is some behind the scenes things going on when you get/set a property which adds some time. I recently discovered using token.gm_name as a global-like variable for large objects is much faster than using a regular property. So, I've recently created a bugger which need to get/set stuff globally for the macro run and will eat up the processing time when using a regular token property. I found it 10 times faster when I used the token.gm_name instead for a temp location when building my array of objects.

I still haven't come up with a viable solution yet for my large db problem, but I'm leaning towards breaking up the data across multiple tokens which is creating a logistics problem in itself. I was to the make the get/set process invisible to the coder so I don't have to worry about what is where when getting data from one source.

User avatar
Rumble
Deity
Posts: 6235
Joined: Tue Jul 01, 2008 7:48 pm

Re: Lib Properties and Campaign life

Post by Rumble »

CoveredInFish wrote: Or is there a reason for placing them on a single libtoken?
eRaz0r and I discussed some of this the other day; it depends on what is being done (we were talking about condition tracking and automation for D&D 4E). Someone other than me discovered that centralizing conditions on a single lib token made the process I was using a lot faster than distributing them. My original method involved storing complex JSONs on each token to represent the conditions it had, and on every initiative cycle, for every token:

1. Retrieve the property
2. Loop through it, applying / removing details as necessary
3. Store the changed property on the token
4. Move to the next token

so every time this happened, every token in the initiative list was being sent over the wire. With a lib token, even if the JSON is slightly more complex, it's only accessing the property once, storing it once, and sending a single token over the wire.

I expected it'll be even faster using the "set/reset" method, if eRaz0r can get it working (and now I'm jealous, because I didn't think of that! Just need to set up a unique ID for creature, and set a property with that ID, and...huh. Excellent)

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Lib Properties and Campaign life

Post by aliasmask »

I guess it depends how big and complex your variable is as to what is the best approach. The smaller the amount of data the more complex it can be without effecting performance too much, but even with small data sets I really do notice a difference in speed right away. I had a form where I would pass my data in the submit between reloads and it was lickety quick. As soon as I decided to save the data to a property and then reload it when the page loaded is when it went from instant to 1/2 second for reload time. It was livable, but noticeable. It was just one object and had 3 layers of complexity (obj(obj(array))) and not very much data.

eRaz0r
Cave Troll
Posts: 41
Joined: Sun Mar 28, 2010 12:29 am

Re: Lib Properties and Campaign life

Post by eRaz0r »

Aliasmask - that's some useful data.

Here's my plan, in some more detail, for those who are interested..

I want to add "Conditions" to my (not yet ready for release) DND4e framework.

The format for them is as simple as I can make it -
They have :
Name (or type? e.g. Dazed)
Source
Target
Text (for display, general reminders etc)
(Possibly a field for calling a macro when they renew.. )
LastsUntil (Start of My Next Turn, Start of Target's Next Turn, End of My / Target's next turn... etc)
isBeneficial (When you delay, in 4e, beneficial effects end, but harmful effects do not)
(TurnImposed, and TurnRemoved - if I want to store some kind of retrospective view of a combat, or support undo, these last two are needed. Otherwise, I'm not sure)

Now here's where it gets tricky.

I need to store Conditions attached to the Target of the effect. But I'm ALSO storing a link to that condition on the token which is responsible for EXPIRING that condition. (When I say "on the token", I actually mean in the Lib:DATA token, but easily referencable by token name)

The reason I do this is to reduce looping.

For example : The Expiring Token for a Dazed (save ends) is the Target of the effect. On the Target's turn, it gets a save to end the effect. The Expiring Token for something like "You gain a +2 to your AC till the end of your next turn" is the Target (and Source) token. The Expiring Token for a power that says "The Target is stunned till the end of your next turn" is the Source token.

So I need to be able to store a list of Expiring Effects on the Expiring Token, which point uniquely to Conditions that are attached to a potentially different token. ( Note that using something like Targ.Name+ConditionName may not be unique. What if two effects cause the Dazed condition, but one is (save ends) and the other is (end of next turn)? )


With this system, I should not have to loop through every condition for every token at the start and end of every turn. I should only have to loop through the list of Expiring Conditions. IF that list for a given token is empty, then there's nothing to do.. move on.


So the challenge here is
a) how do I uniquely identify a condition? TargetName + Condition Name + Number?
b) How do I store this so that it's fast?
I'm leaning towards having a property for each Target in a lib:AffectingConditions token.
This would be a JSON object as follows :

{
"Dazed0" : { ..., "LastsUntil":"Save" }
"Dazed1" : { ..., "LastsUntil":"EndTargNextTurn" }
}

And then perhaps a separate Lib:ExpiringConditions token with a property for each Expiring Token,
This might look like

[ "Targ1:Dazed0", "Targ2:Stunned1" ]
or
{ "Targ1" : "Dazed0" , "Targ2" : "Stunned1" }

whichever performs better.


We'll see how that works :D

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Lib Properties and Campaign life

Post by aliasmask »

You may want to check out Plothos's Init Panel. You could build a hook that will apply/un apply affects when it's that time. I plan to do something similar when I finally have enough of the pieces to put together my own framework.

Init Panel
Last edited by aliasmask on Wed Jul 28, 2010 6:00 pm, edited 1 time in total.

eRaz0r
Cave Troll
Posts: 41
Joined: Sun Mar 28, 2010 12:29 am

Re: Lib Properties and Campaign life

Post by eRaz0r »

Thanks - I'll give that a look.
I hadn't even thought much about the UI for changing initiative.

My plan had been to create a Condition Editor Dialog to view/edit/add conditions to a target - GM only.

Then pop up a dialog at the start/end of turns with a checkbox for all ending conditions to confirm that they did, indeed, end.

That way, if the framework misses something, the GM can override it easily.
Power to the GM is my motto!

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Lib Properties and Campaign life

Post by aliasmask »

All the init data in the plug-in is handled on the lib token (I think).

Post Reply

Return to “Macros”