Okay, so I tried to repurpose the above script for use in my script's context, but it doesn't seem to be working. Here's how I used it: var attrLookup; on('ready',function(){ "use strict"; attrLookup = function(character,name,caseSensitive){ let match=name.match(/^(repeating_.*)_\$(\d+)_.*$/); if(match){ let index=match[2], attrMatcher=new RegExp(`^${name.replace(/_\$\d+_/,'_([-\\da-zA-Z]+)_')}$`,(caseSensitive?'i':'')), createOrderKeys=[], attrs=_.chain(findObjs({type:'attribute', characterid:character.id})) .map((a)=>{ return {attr:a,match:a.get('name').match(attrMatcher)}; }) .filter((o)=>o.match) .each((o)=>createOrderKeys.push(o.match[1])) .reduce((m,o)=>{ m[o.match[1]]=o.attr; return m;},{}) .value(), sortOrderKeys = _.chain( ((findObjs({ type:'attribute', characterid:character.id, name: `_reporder_${match[1]}` })[0]||{get:_.noop}).get('current') || '' ).split(/\s*,\s*/)) .intersection(createOrderKeys) .union(createOrderKeys) .value(); if(index<sortOrderKeys.length && _.has(attrs,sortOrderKeys[index])){ return attrs[sortOrderKeys[index]]; } return; } return findObjs({ type:'attribute', characterid:character.id, name: name})[0]; }; }); //... on('chat:message', function(msg) { if (msg.type != 'api') return; var parts = msg.content.split(' '); var command = parts.shift().substring(1); function ReorderRepeating(token, attrname){ let who = getObj('player',msg.playerid).get('displayname') _.chain(token) .map((o)=>getObj('graphic',o._id)) .reject(_.isUndefined) .filter((t)=>t.get('represents').length) .map(t=>{ return {token:t,character:getObj('character',t.get('represents'))};}) .reject(o=>_.isUndefined(o.character)) .map(o=>{ o.attrs=_.reduce(attrname,(m,a)=>{ let attr=attrLookup(o.character,a,false); m[a]=(attr ? attr.get('name') : '[MISSING]'); return m; },{}); return o; }) .map(o=> `<div><h3>${o.character.get('name')}</h3><ul>${_.map(o.attrs,(a,n)=>`<li><b>${n}</b>-<code>${a}</code></li>`).join('')}</ul></div>`) .tap(out=>{ sendChat('',`/w ${who} ${out.join('')}`); }); } // Don't run if it's any other command if (command == 'combat') { //... let StrengthsA = getAttrByName(attacker.id, "repeating_weapons_$0_Strengths") || ""; let StrengthsB = getAttrByName(defender.id, "repeating_weapons_$0_Strengths") || ""; let WeaknessA = getAttrByName(attacker.id, 'weaknesses'); let WeaknessB = getAttrByName(defender.id, 'weaknesses'); ReorderRepeating(selectedToken, "repeating_weapons_$0_Strengths"); Which doesn't do anything and only returns in the chat: (From ): ??? 0 - [MISSING] r - [MISSING] e - [MISSING] p - [MISSING] a - [MISSING] t - [MISSING] i - [MISSING] n - [MISSING] g - [MISSING] _ - [MISSING] w - [MISSING] o - [MISSING] s - [MISSING] $ - [MISSING] S - [MISSING] h - [MISSING] I can only assume I either messed up somewhere while porting it over into the script context, or I'm not using it correctly. Help? Also, if it's not too much of a bother, I would love an in-depth explanation of how this works, since Regex and Underscore.js stuff flies completely over my head.