Scott C. said: Heh, not sure I deserve to be called an expert, but here it goes. And I'm sure Aaron will drop by with the actual technical explanation. Because getAttrs is asynchronous and setAttrs is asynchronous, you really can't tell what order they will fire in. Usually, it will be the order listed, but it doesn't have to be. And there's no way to control the order if they're organized like that example; it's all just based on whichever one runs first - the very definition of a race condition. In your example, depending on what versioning() does, this may be perfectly fine. That confirms what I was thinking. Versioning in the examples I've looked at that use this design pattern always has more getAttrs and setAttrs inside it - its basically a recursive script, that on each recursion, does one set of version changes (with its own getAttrs and setAttrs inside it, and a setattrs beside it). It struck me that if any of those version loops changed the same states, they could work in the wrong order because of asynchronicity and this particular structure. Whereas if they combined the version setting and version changes setAttr into one, they loop into the next recursion inside the setAttrs's callback function, they avoid that danger because that doesnt run until the setAttrs is finished. Your version of handling versioning does seem impressive, but maybe a bit extravagant! Personally I don't mind a bit of a delay during a version change, because it only happens once, on sheet opening, after aversion change. And its easier to compartmentalise the code for each version. I think this might be overstating things a bit: If at all possible, you should avoid doing Cascades of getAttrs -> setAttrs -> getAttrs -> repeating as it is extremely time consuming. The normal operation of many sheets will have some of this going on automatically. You change a stat, that triggers getAttrs/setAttrs to recalculate the stat bonus; that then triggers getAttrs/setAttrs to recalculate a handful of skills and other derived stats that that use that stat; that might then trigger another getAttrs/setAttrs change to anything they effect, until the changes cascade out and finally settle. For some really heavy sheets this might be noticeable, but for most it wont. I prefer modularisation like that and taking a small performance hit, though if it took 2 or more seconds everytime you made a change to a sheet that would definitely need changing. I have heard some sheets do wrestle with that problem - once I make sheets big enough to face that problem, I may change my tune :) Another advantage of sheets written this way is anyone can maintain them - someone could take over from me and find the code mostly understandable and make any changes they needed to. I think thats really important for community sheets, and is worth a slight drop in optimisation. Anyway thank you, you did confirm what I thought had ti be the case with those recursive versioning scripts.