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

State Data Won't Persist Between Sandbox Sessions

1588495589

Edited 1588496117
I am attempting to migrate a registry of image object data (already held in the state variable) to a new location and format within the state variable.&nbsp; However, when I run the function to copy over all of the data, no matter what I try I can't get the data to stick.&nbsp; Everything works perfectly fine until I restart the sandbox, at which point the value of my new state.VAMPIRE.Assets.AssetLibrary property is reset to an empty object. Here is the function I am using to migrate the data.&nbsp; I originally used a getter to access the state variable, and wasn't (excessively) stringifying all of the data, but this is my latest attempt to get it to work, to no avail: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;Values&nbsp;of&nbsp;constants&nbsp;used&nbsp;in&nbsp;the&nbsp;function: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GAMENAME:&nbsp;"Vampire", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PAGES:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GAME:&nbsp;"-Lt3Ml6LYAIgYbWB6IVq", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SplashPage:&nbsp;"-Lz0ONP6PmgW9T06kmiy" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REGISTRY&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;IMG()&nbsp;{&nbsp;return&nbsp;state[C.GAMENAME].Media.imgregistry;&nbsp;}&nbsp;//&nbsp;The&nbsp;old&nbsp;image&nbsp;registry&nbsp;I'm&nbsp;migrating&nbsp;from. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; migrateRegistryIMG &nbsp; = &nbsp;()&nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; errorLines &nbsp; = &nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets &nbsp; = &nbsp;state [ C . GAMENAME ] . Assets &nbsp; || &nbsp;{ AssetLibrary :&nbsp;{}}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary &nbsp; = &nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary &nbsp; || &nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;state[C.GAMENAME].Assets&nbsp;=&nbsp;{AssetLibrary:&nbsp;{}};&nbsp;//&nbsp;(A&nbsp;reset&nbsp;button&nbsp;I&nbsp;can&nbsp;uncomment&nbsp;to&nbsp;ensure&nbsp;I'm&nbsp;starting&nbsp;fresh.) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for &nbsp;( const &nbsp; itemData &nbsp; of &nbsp; Object . values ( REGISTRY . IMG ))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; mediaObj &nbsp; = &nbsp; getObj ( "graphic" , &nbsp;itemData . id ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;( mediaObj )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; objID &nbsp; = &nbsp; JSON . stringify ( mediaObj . id ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ]&nbsp; = &nbsp;{} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . name &nbsp; = &nbsp; JSON . stringify ( itemData . name ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . type &nbsp; = &nbsp; JSON . stringify ( "image" ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . page &nbsp; = &nbsp; JSON . stringify ( _ . findKey ( C . PAGES ,&nbsp; v &nbsp; =&gt; &nbsp; v &nbsp; === &nbsp;itemData . pageID )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . layer &nbsp; = &nbsp; JSON . stringify ( mediaObj . get ( "layer" )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . zIndex &nbsp; = &nbsp; JSON . stringify ( itemData . zIndex ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos &nbsp; = &nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . top &nbsp; = &nbsp; JSON . stringify ( itemData . top ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . left &nbsp; = &nbsp; JSON . stringify ( itemData . left ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . height &nbsp; = &nbsp; JSON . stringify ( itemData . height ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . width &nbsp; = &nbsp; JSON . stringify ( itemData . width ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . state &nbsp; = &nbsp; JSON . stringify ( itemData . curSrc ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . isActive &nbsp; = &nbsp; JSON . stringify ( itemData . isActive ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . activeLayer &nbsp; = &nbsp; JSON . stringify ( itemData . activeLayer ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . wasModeUpdated &nbsp; = &nbsp; JSON . stringify ( Boolean ( itemData . wasModeUpdated )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . modes &nbsp; = &nbsp; JSON . stringify ( itemData . modes ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . srcs &nbsp; = &nbsp; JSON . stringify ( itemData . srcs ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;( itemData . padID )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads &nbsp; = &nbsp;{ deltas :&nbsp;{}}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . ids &nbsp; = &nbsp; JSON . stringify ([ itemData . padID , &nbsp;itemData . partnerID ]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . funcName &nbsp; = &nbsp; JSON . stringify ( DragPads . PadsByID [ itemData . padID ] . funcName ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . startActive &nbsp; = &nbsp; JSON . stringify ( true ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; pad &nbsp; = &nbsp; getObj ( "graphic" , &nbsp;itemData . padID ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . deltas . deltaTop &nbsp; = &nbsp; JSON . stringify ( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pad . get ( "top" )&nbsp; - &nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . top &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . deltas . deltaLeft &nbsp; = &nbsp; JSON . stringify ( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pad . get ( "left" )&nbsp; - &nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . left &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . dragPads . deltas . deltaHeight &nbsp; = &nbsp; JSON . stringify ( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pad . get ( "height" )&nbsp; - &nbsp;state [ C . GAMENAME ] . Assets . AssetLibrary [ objID ] . pos . height &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; else &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorLines . push ( `Error&nbsp;finding&nbsp;object&nbsp;with&nbsp;key&nbsp;${ D . JS ( itemData . name )}` ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;( errorLines . length ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D . Alert ([ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;h4&gt;Image&nbsp;Conversion&nbsp;Errors:&lt;/h4&gt;" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorLines . join ( "&lt;br&gt;" ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] . join ( "" )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D . Flag ( "Image&nbsp;Conversion&nbsp;Successful!" ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} (There's also a line to set deltaWidth in dragPads, but every time I try to edit this post to include it, my edits don't stick any more than my state data does :P ) Running the above function returns no errors, and results in the desired new registry object assigned to state.VAMPIRE.Assets.AssetLibrary , with IDs as the keys and each value containing the object data (example below, showing only one entry): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state . VAMPIRE . Assets . AssetLibrary &nbsp; = &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-LupWXX6TCU1hrUrkfbN" :&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name :&nbsp; "WeatherMain_1" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type :&nbsp; "image" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page :&nbsp; "GAME" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layer :&nbsp; "walls" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zIndex :&nbsp; 124 , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos :&nbsp;{ top :&nbsp; 520 ,&nbsp; left :&nbsp; 795 ,&nbsp; height :&nbsp; 1040 ,&nbsp; width :&nbsp; 1590 }, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state :&nbsp; "brightheavysnow" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isActive :&nbsp; false , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; activeLayer :&nbsp; "map" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wasModeUpdated :&nbsp; true , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; modes :&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Active :&nbsp;{&nbsp; isForcedOn :&nbsp; "LAST" ,&nbsp; isForcedState :&nbsp; true ,&nbsp; lastActive :&nbsp; true ,&nbsp; lastState :&nbsp; "brightheavysnow" &nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Inactive :&nbsp;{&nbsp; isForcedOn :&nbsp; null ,&nbsp; lastState :&nbsp; null &nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Daylighter :&nbsp;{&nbsp; isForcedOn :&nbsp; "NEVER" ,&nbsp; lastState :&nbsp; null &nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Downtime :&nbsp;{&nbsp; isForcedOn :&nbsp; "NEVER" ,&nbsp; lastState :&nbsp; null &nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Complications :&nbsp;{&nbsp; isForcedOn :&nbsp; null ,&nbsp; lastState :&nbsp; null &nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Spotlight :&nbsp;{&nbsp; isForcedOn :&nbsp; "NEVER" ,&nbsp; lastState :&nbsp; null &nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; srcs :&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; brightlightsnow :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98106912/ClHOiRXtnxYmHJxozVT8rg/thumb.png?1575009896" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98106912/ClHOiRXtnxYmHJxozVT8rg/thumb.png?1575009896</a> " , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; darkheavysnow :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98105311/05YcLo3dxPamoKBBZbhjhw/thumb.png?1575006139" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98105311/05YcLo3dxPamoKBBZbhjhw/thumb.png?1575006139</a> " , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; darklightsnow :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98105315/jiduBVDEw_Wi7S5EGm3r4w/thumb.png?1575006145" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98105315/jiduBVDEw_Wi7S5EGm3r4w/thumb.png?1575006145</a> " , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; brightheavysnow :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98105357/jPk43xiLgqfqmDjLvFM37w/thumb.png?1575006278" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98105357/jPk43xiLgqfqmDjLvFM37w/thumb.png?1575006278</a> " , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lightrain :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98105503/5Ttj1u5KoyheaxW4EOrsDg/thumb.png?1575006612" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98105503/5Ttj1u5KoyheaxW4EOrsDg/thumb.png?1575006612</a> " , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; heavyrain :&nbsp; " <a href="https://s3.amazonaws.com/files.d20.io/images/98105500/yARovGTh6zb94eJZ6F7uNg/thumb.png?1575006606" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/98105500/yARovGTh6zb94eJZ6F7uNg/thumb.png?1575006606</a> " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dragPads :&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ids :&nbsp;[&nbsp; "-M6OWvVnJneZe-VcEMXi" ,&nbsp; "-M6OWvVo2ATukCAYReLG" &nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcName :&nbsp; "getWeatherReport" , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startActive :&nbsp; true , &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deltas :&nbsp;{&nbsp; deltaTop :&nbsp; 0 ,&nbsp; deltaLeft :&nbsp; 0 ,&nbsp; deltaHeight :&nbsp; -20 ,&nbsp; deltaWidth :&nbsp; -20 &nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} Everything works fine after I run migrateRegistryIMG() --- other scripts are able to access the above data, both to read and to write.&nbsp; However, once I restart the sandbox, all of the data disappears and state.VAMPIRE.Assets.AssetLibrary is reset to an empty object.&nbsp; (Curiously, the "AssetLibrary" key itself persists between sandbox restarts, even though it's created at the same time and within the same function as the rest of the data.) Is there something in my data that is preventing a proper update of the state variable?&nbsp; Is it possible that some issue with namespacing or the like is giving me a "state" reference to something other than the actual state variable? Any help would be very much appreciated!&nbsp; I've got a game coming up soon and I'd really like to solve this before then!
1588530480
GiGs
Pro
Sheet Author
API Scripter
That seems like a lot of data, and maybe you are using the state way beyond its intended goal. Is there a chance you are exceeding the state size limit which is 2MB IIRC?&nbsp; I dont know why the total state would vanish if something wasnt resetting it though.
Ahhh, that might indeed be it.&nbsp; I wasn't aware there was a limit to the state variable.&nbsp; I am storing some rather silly things in there, like my debug log; I'll try clearing that out and see if anything changes.&nbsp; Thanks!
1588581123

Edited 1588581134
Well, my rough measurement of my state variable seems to confirm your theory.&nbsp; Thanks again for your help!
1588597938
The Aaron
Roll20 Production Team
API Scripter
There isn't a reason to put static data in the state anyway.&nbsp; Just create an object that your script uses to reference the information.
1588648608

Edited 1588648838
That's basically what I'm doing:&nbsp; I have a state entry for each of my objects containing additional data than that contained in the object itself (e.g. when it should be toggled on, keywords for the image sources I'll be changing it into, data for text objects that lets my justification functions work).&nbsp; On initialization, my Assets script builds class instances of each object, containing all of my custom methods: The rest of my scripts (once I'm finished with this refactor) will deal with the instance objects only, making changes to them instead of to the sandbox objects themselves.&nbsp; Then, a static "applypendingchanges" method iterates through the record of changes logged in the class instances, filters them down to only those changes that will actually result in a change of the object, and finally sets all the pending changes with a single call of object.set(). This has proven much faster in testing, as it cuts down a great deal on redundant object setting that can happen when a bunch of scripts interact and, say, set the same property on an object multiple times.&nbsp; (It also reduces by at least an order of magnitude the number of calls to Roll20 functions, which has helped given the recent issues with the Roll20 API) (As an update: The reason my state variable was so inflated was due to a memoization function I was using to log html code for chat-based menus --- it alone held a megabyte of data when I finally pruned it. My state length is down to 1 MB and everything is working smoothly.&nbsp; Thanks again to you both for your help!)
1588648967
The Aaron
Roll20 Production Team
API Scripter
Sounds great but none of that needs to be in the state.&nbsp; Just create a global object to store your constructed object instances in and reference that like you would the state.&nbsp; The state can't store functions anyway, and if you're constructing it every time you start the API, it's pointless to store it in the state.
But what about data that I need to persist between sandbox restarts?&nbsp; There isn't a way to create a persistent global object outside of the state variable, is there?
1588716702
GiGs
Pro
Sheet Author
API Scripter
You could store it in a character or handout.
That's true, and something I considered when I briefly worried I might need the 2 MB of state I was using --- but I've cut it in half with just a bit of pruning, and once I'm finished migrating over my old objects registry to the new one, I won't have a bunch of doubled-up information in my state variable.&nbsp; Are there performance (or other) reasons to prefer storing data as a JSON string in a hidden handout, rather than the state variable, as long as I'm sufficiently below the 2 MB cap?&nbsp;
1588730217
The Aaron
Roll20 Production Team
API Scripter
My understanding is that the state is synchronized into a database on a timer. Handouts are synchronized into firebase on change.&nbsp; Handouts have the added benefit that you can copy them between Games.&nbsp;
Hmm, I'm not familiar enough with the back end to know which of those is "better" in terms of performance --- I've been assuming the state variable is faster to work with if scripts are making a lot of changes in a short amount of time? (And yeah, regardless of which is better, this discussion has given me the idea to at least back up as much as I can via handouts objects!)