Regarding the speed, I totally agree! It makes me miss working from home on a less challenging job. =D Writing that spending function was loads of fun and reminds me of an earlier question about how you can test Javascript without uploading it to Roll20 every time. I do a couple of things: I use an editor with context highlighting for Javascript. It's Vim for me, but there are others you can use (Sublime Text, Ultraedit, etc). Get one for your platform you're comfortable with. Context highlighting will help you avoid most syntactic problems. Make sure your editor supports a static analysis tool like ESLint. For me, when I save the file, it runs ESLint on it and displays any errors/potential errors. This works best with a proper config file, I posted mine a while back (I'm on my phone now or I'd repost), but the default one will catch a fair amount. You can set up a javascript environment like Node.js and use a unittests tool like Jest. Depending on your environment (and developer pain threshold), that could be difficult. Edit: My .eslintrc.js file (you'll probably want to take out the Unix part, unless you're on a Mac): module.exports = {
"env": {
},
"globals": {
"WeakMap": true,
"Set": true,
"setAttrs": true,
"setInterval": true,
"clearInterval": true,
"clearTimeout": true,
"setTimeout": true,
"playerIsGM": true,
"getObj": true,
"findObjs": true,
"filterObjs": true,
"createObj": true,
"sendChat": true,
"log": true,
"toFront": true,
"toBack": true,
"randomInteger": true,
"setDefaultTokenForCharacter": true,
"spawnFx": true,
"spawnFxBetweenPoints": true,
"spawnFxWithDefinition": true,
"playJukeboxPlaylist": true,
"stopJukeboxPlaylist": true,
"sendPing": true,
"state": true,
"globalconfig": true,
"_": true,
"Campaign": true,
"getAllObjs": true,
"getAttrByName": true,
"onSheetWorkerCompleted": true,
"on": true,
"Promise":true,
"Uint32Array":true,
"takeCardFromPlayer":true,
"giveCardToPlayer":true,
"recallCards":true,
"shuffleDeck":true,
"drawCard":true,
"cardInfo":true,
"playCardToTable":true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2017,
"ecmaFeatures": {
"impliedStrict": true,
"experimentalObjectRestSpread": true
},
"sourceType": "module"
},
"plugins": [
],
"rules": {
"no-console": "warn",
"linebreak-style": [
"error",
"unix"
],
"semi": [
"error",
"always"
],
"comma-dangle": [
"error",
"never"
]
}
};