You're making progress! It is looking much more concise. A couple of small points... incorporate them or not as you see fit... Line 666 (and continuing) You split() on a single space, and then switch(){} on argument names like "--this". You'd probably gain some forgiveness by splitting on any number of white spaces, and even more forgiveness by splitting on whitespace followed by double-hyphens. I would also do it as a .forEach loop just because that isn't destructive to your args variable, in case you need it later. All of that would look like... let args = msg.content.split(/\s+--/).slice(1); args.forEach(a => { // Loop all attributes switch (a) { case "help": // Show help in Chat // args.splice(0, 1); // <== don't need this line any more (there was a typo in your code, here, too, just FYI) // run help code
break;
case "debug":
// run debug code
break;
// ...
} (Other places where you use a for() loop against an array I would probably just use a forEach(), too... but that's just a preference thing to save me typing longer names and brackets everywhere.) Lines 121 - 130 (createOrSetAttr) Your createOrSetAttr function doesn't actually return an object. There's nothing wrong with that, if you never need it, but it wouldn't hurt to return the object which you have located... at least as far as decomposing and reusing this function elsewhere. You could imagine a time when you would want to have the attribute you just created, and it costs you nothing to ignore the return. However, as you currently have it coded, where you aren't actually returning the attribute object, you need never declare it. Just wrap it in a viscous coating of gelatinous protection... also known as an OR case: const createOrSetAttr = (atnm, val, cid) => { // Set an individual attribute if it exists, otherwise create it. (findObjs({type: 'attribute', characterid: cid, name: atnm})[0] ||
createObj('attribute', {name: atnm, current: val, characterid: cid})).set('current', val);
};