Hi, EDIT - After some further testing, the previous token was null at the time of testing. Hack solution is to store the current token token-id in the name field of my GM token, then retrieve it when the next token is current and so on. The code below is essentially Aarons OnMyTurn script with a few extras. On advancing the turn tracker the following occurs 1. It whispers an end of turn message from the token that just had its turn to the chat for the gm, and runs token-mod to delete or decrement any counter based status markers, the code just has -blue as an example, but I use many more that need to be decremented. 2. It whispers a start of turn message from the token that now has initiative to the chat for the gm, if that token(and related sheet) has an ability called OnMyTurn that will be called instead. In addition it lists the current status markers on the token to chat, after any have been deleted by the call to token-mod, you can put what you like in that call re statusmarkers, but i remove reaction, dodge, disadvantage and readied status token  markers at the start of a tokens turn.  3. It uses sendPing to move the map for the GM to the active token. 4. Every now and then, mainly after a long pause, it seems to run things twice, ie, advance turn tracker, and it will do everything twice. Thinks to note 1.I hard code my player ID for the ping, I get that using Aarons code in a previous call. Most times the GM is player1, so there are better ways to get the player ID. on('ready',function(){     'use strict';     var players=findObjs({_type:'player'});     _.each(players,function (obj){         log('Player '+obj.get('displayname')+' has id: '+obj.get('id'));     }); }); 2.The token-mod report parm I use is 'after' not a currently listed parm, but it doesn't throw an error, and gives me what I want. 3. It would be easy to add a OnEndMyTurn ability as well, but I haven't found a need. 4. I dont' put things in the turn tracker that are not tokens, ie npcs or players only, no status or timers etc, so I'm not sure what would happen if you did. I use a modified version of timetracker to keep a track of events that last longer than a round and status markers for a round or less. on('ready', () => {     const resolver = (token,character) => (text) => {         const attrRegExp = /@{(?:([^|}]*)|(?:(selected)|(target)(?:\|([^|}]*))?)\|([^|}]*))(?:\|(max|current))?}/gm;              const attrResolver = (full, name, selected, target, label, name2, type) => {             let simpleToken = JSON.parse(JSON.stringify(token));             let charName = character.get('name');             type = ['current','max'].includes(type) ? type : 'current';             const getAttr = (n, t) => (                     findObjs({type: 'attribute', name:n, characterid: character.id})[0]                     || {get:()=>getAttrByName(character.id,n,t)}                 ).get(t);             const getFromChar = (n,t) => {                 if('name'===n){                     return charName;                 }                 return getAttr(n,t);             };             const getProp = (n, t) => {                 switch(n){                     case 'token_name':                         return simpleToken.name;                     case 'character_name':                         return charName;                     case 'bar1':                     case 'bar2':                     case 'bar3':                             return simpleToken[`${n}_${'max'===t ? 'max' : 'value'}`];                 }                 return getFromChar(n,t);             };             if(name){                 return getFromChar(name,type);             }             return getProp(name2,type);         };         return text.replace(attrRegExp, attrResolver);     };     const checkOnMyTurn = (obj,prev) => {         let to=JSON.parse(obj.get('turnorder')||'[]');         let toPrev=JSON.parse(prev.turnorder||'[]');         if(to.length && to[0].id!=='-1' && to[0].id !== (toPrev[0]||{}).id){             let token = getObj('graphic',to[0].id);             let prevtoken = getObj('graphic',toPrev[0].id);             if(token && token.get('represents')){                 let character = getObj('character',token.get('represents'));                                  sendChat(prevtoken.get('name'),'/w gm Ends Turn');                 sendChat('','!token-mod --ids '+prevtoken.id+' --set statusmarkers|-blue');                                  let ability = findObjs({                     name: 'OnMyTurn',                     characterid: character.id                 }, {caseinsensitive: true})[0];                 if(ability){                     let content = resolver(token,character)(ability.get('action')).replace(/\[\[\s+/g,'[[');                     try {                         sendChat(character.get('name'),content);                     } catch(e){                         log(`OnMyTurn: ERROR PARSING: ${content}`);                         log(`OnMyTurn: ERROR: ${e}`);                     }                 } else {                     sendChat(token.get('name'),'/w gm Starts Turn');                 }                                  //using 'after' in report section, not a listed parm, but seems to work lol, ie whats reported is after the changes                 sendChat(token.get('name'),'!token-mod --ids '+token.id+' --set statusmarkers|-React2::3922536|-Dodging::243503|-ShieldSpell::329207|-Readied::243500|-Disadvantage::243630 --report gm|"Status Markers -> {statusmarkers:after}."');                                  setTimeout(function() {                     toFront(token);                     sendPing(token.get('left'), token.get('top'), Campaign().get('playerpageid'), null, true, "-MYifojubSmW72d07Dz2")                 }, 1000);             }         }     };          on(         'change:campaign:turnorder',         (obj,prev)=>setTimeout(()=>checkOnMyTurn(Campaign(),prev),1000)     ); });