Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

API Update 5/8: State Object Persistence

May 08 (12 years ago)
Riley D.
Roll20 Team

There's a new update that just went live. From now on, the state object will be persisted between play sessions. Note that it only persists simple objects, so for example you can't store a function reference or something like that on there, but numbers, strings, booleans, other simple objects, are all fine. Basically it's doing JSON.stringify() and JSON.parse(), so anything that those can work with is fine.

The state object is not stored as a part of your campaign file (it's saved separately), so you should store any API-related information in there when possible as it won't increase the size of your campaign file, and won't produce longer loading times for your game's players. You can also store information on specific objects, for example by doing state[obj.id] = {moved: true}

EDIT: Also, clearInterval and clearTimeout now work properly.

May 08 (12 years ago)
Konrad J.
Pro
API Scripter

Wow!  Thanks.  I can see the API doing some amazing things as you continue to add to it.  But I also can't wait for you to get to some UI, card deks, etc. work done! :)  You need cloning, but hopefully they get the bugs out of the process so we don't end up with evil Riley!

May 08 (12 years ago)
Alex L.
Pro
Sheet Author

Thanks as usual Riley will port my code over when i get a chance.

May 08 (12 years ago)
Konrad J.
Pro
API Scripter

My Stop Watch works perfectly now!  I'll post it later when I clean it up a bit!  Thanks again!

Awesome, thanks Riley!

This will be awesome for my snapshot script, and I have a few other ideas that will make good use of this as well.

May 09 (12 years ago)

Riley D. said:

You can also store information on specific objects, for example by doing state[obj.id] = {moved: true}

Does this mean I can store attribute like values on tokens instead of journals for my monsters? For example, I'm adding !+thp and !-thp chat commands to my 4e toolbox and it would make using temp hp powers on monsters easier to use if this is true.

May 09 (12 years ago)
Riley D.
Roll20 Team

HoneyBadger said:

Riley D. said:

You can also store information on specific objects, for example by doing state[obj.id] = {moved: true}

Does this mean I can store attribute like values on tokens instead of journals for my monsters? For example, I'm adding !+thp and !-thp chat commands to my 4e toolbox and it would make using temp hp powers on monsters easier to use if this is true.
I'm not sure I totally understand the question. But, to hopefully help clarify, the state object is a totally separate object from anything else. However, every ID in the system (e.g. the ID of a token, the ID of a character, etc.) is globally unique. So what you can do is store information about a token, for example the number of temp HP remaining, in the state object at state[obj.id]. The state object is saved between sessions now, so when you next play it will still have that value. 

So that begs the question -- what should I store in the state object, and what should I store on the token itself? Basically, you should store values on the token that match token properties and you want players to have access to change So if you want to track TempHP in Bar2 so that players can change it as well, store it there. If you don't want the players to have access to change the TempHP directly, only through chat commands, store it in the state object, since only the API can change those values.  You wouldn't want to, for example, store the number of steps a patrolling token has taken in Bar3, as that has nothing to do with what the players want to edit in-game.

Especially this should cause you to not store things like JSON strings in the Notes or GM Notes fields, as again those aren't intended for that and I can't guarantee something I do in the future wouldn't break your ability to store things there.

Hope that helps, let me know if it didn't :-)

May 09 (12 years ago)

Yeah, it helps some. I'm just trying to find a way to easily manage (via api chat commands) temp hp on monster tokens not linked to any journal (character sheet). Thus they don't have attributes like characters do.

May 09 (12 years ago)
Riley D.
Roll20 Team

Yeah, then you could use the state object for that.

May 10 (12 years ago)

How do I retrieve a value from the state object? Here's what I have for setting the value.

state[oTargetToken.id] = {"TempHP": iTempHPtoAdd};

Also, what value would be returned if the target token didn't have a temp hp value yet?

May 10 (12 years ago)
Alex L.
Pro
Sheet Author
if(oTargetToken.id in state) {
   // We have state stuff
   var obj = state[oTargetToken.id];
   
   if("TempHP" in obj) {
     // We have temp hp
     var tmpHp = obj["TempHP"];
   } else {
     // OMG no TempHp wtf am i doing?
   }
} else {
   // Nothing for this token
}
May 10 (12 years ago)

Oh... I never would have guessed that 'in state' thing. Bleh. That's new to me.

-edit- Ah, I see... 'in' works for any json object / array?

May 10 (12 years ago)
Alex L.
Pro
Sheet Author

HoneyBadger said:

Oh... I never would have guessed that 'in state' thing. Bleh. That's new to me.

Its how you tell if a member is in an object in JavaScript it will work with any object and as state is an object.

I would really recommend never using the id of anything as the key for state you will live to regret it, do something like myscriptname_id instead this will stop other scripts overriding your data.

also is oTargetToken a roll20 token object because if it is you should really use the get function and _id.
May 10 (12 years ago)

It is a roll20 token. I'm still figuring things out. My experience with this kind of scripting is limited to nwscript from Biowares NWN1 and maptool macroscript. Similar... and close enough for me to get the basic gist of things, but the finer points still escape me. Right now, everything seems to work. So I'll start refining them to be cleaner code soon.

May 11 (12 years ago)

Alex L. said:

I would really recommend never using the id of anything as the key for state you will live to regret it, do something like myscriptname_id instead this will stop other scripts overriding your data.

also is oTargetToken a roll20 token object because if it is you should really use the get function and _id.
I'm starting to re-write my scripts and I'm trying to clean up the code somewhat. What do you mean by get function and _id instead?

May 11 (12 years ago)
Konrad J.
Pro
API Scripter

Something I have found useful for making sure I have all the ;, {, ) in the right place is http://www.jslint.com/

Go all the way to the bottom under Options you can set the Tolerate options to true if you like for "missing 'use strict' pragma", "many var statements per function", and "messy white space".

paste your completed script into the window it tells you to.  Press the JSLint buttom below this window.  Have a look at all your errors.

Errors You Can Ignore

'sendChat' was used before it was defined.

Only worry about this kind of error if its a function you  wrote.  The rest or Roll20 and the JSLint checker doesn't know about any Roll20 stuff.

Unexpected dangling '_' in '_type'.

Again if this is in a line referencing something for Roll20 then ignore this error.


Another thing I like to do is look at others code to get ideas and find out how to write certain things.  ALex L's code is good for this.

Also don't use the Roll20 editor.  I'm using Notepad++ now and it works great.

This is a good article...

http://www.w3.org/wiki/JavaScript_best_practices

Try not to use cryptic variable names.  Too short is just as bad as too long!

May 12 (12 years ago)
Alex L.
Pro
Sheet Author

HoneyBadger said:

Alex L. said:

I would really recommend never using the id of anything as the key for state you will live to regret it, do something like myscriptname_id instead this will stop other scripts overriding your data.

also is oTargetToken a roll20 token object because if it is you should really use the get function and _id.
I'm starting to re-write my scripts and I'm trying to clean up the code somewhat. What do you mean by get function and _id instead?

you should be using oTargetToken.get("_id"); not oTargetToken.id;

May 12 (12 years ago)

What's the difference?

May 12 (12 years ago)
Alex L.
Pro
Sheet Author

HoneyBadger said:

What's the difference?

Riley told us to use get, I expect it is what does all the checks to make sure we don't do anything stupid, so using id I expect you might be able to accidentally set it to something. Any way the docs say to use get do you need a better reason than that?


May 12 (12 years ago)

Yeah. Especially when Riley posted: state[obj.id] = {moved: true}

May 12 (12 years ago)
Alex L.
Pro
Sheet Author

HoneyBadger said:

Yeah. Especially when Riley posted: state[obj.id] = {moved: true}

Fine do what you like you obviously know more about programming than I do, because Riley loves to add pointless functions into the API and he just felt there had to be a get and set function as well as the object.field syntax and the object[field] syntax.

It couldn't possibly be because its a bitch to make working private members that aren't static in JavaScript and that there are no get set functions like in c# so to filter out crap and prevent you from setting values on fields you aren't meant to set you need a function. </sarcasm>

@Riley i apologise if it does do nothing but for the love of god why!!!


May 13 (12 years ago)

Well state[obj.id] = {"Temp HP": iTempHPtoAdd} works... and I can retrieve it with state[obj.id]["TempHP"] ... so I dunno. I'm just trying to cut down on excess lines, lol.

May 13 (12 years ago)
Riley D.
Roll20 Team

Haha. You do indeed need to use the get() and set() functions for properties. The *one* exception I made is for the id property, since it's so frequently accessed and it never changes I added a shortcut so that you can do obj.id if you wish. 

Sorry for letting this thread go on so long without a response, I was out of town.

May 13 (12 years ago)
Konrad J.
Pro
API Scripter

Riley D. said:

Haha. You do indeed need to use the get() and set() functions for properties. The *one* exception I made is for the id property, since it's so frequently accessed and it never changes I added a shortcut so that you can do obj.id if you wish. 

Sorry for letting this thread go on so long without a response, I was out of town.

Out of town!?  You must have a thousand emails to answer.  WHo the heck let you out of town?

May 13 (12 years ago)
Riley D.
Roll20 Team

Konrad J. said:

Riley D. said:

Haha. You do indeed need to use the get() and set() functions for properties. The *one* exception I made is for the id property, since it's so frequently accessed and it never changes I added a shortcut so that you can do obj.id if you wish. 

Sorry for letting this thread go on so long without a response, I was out of town.

Out of town!?  You must have a thousand emails to answer.  WHo the heck let you out of town?
I seriously did have like 60 emails for only being gone 48 hours...not to mention all the forum posts. Eesh.