I have pasted the entire script here, which, honestly, I know nothing about. All of my experience with these scripts and macros is taking things I've found on the forums and changing just enough of them to make it roll the dice we need without breaking the thing. /* SimpleDoorControls Use Creating a linked door system ----------------------------- Verify you're on the Token/Object Layer. Place a graphic of a door or other barrier in the closed position. Name that token DoorClosed (all one word, and yes the D and C need to be capitalized). Place a graphic of a door in the desired open position. Name that token DoorOpen (all one word, and yes the D and O need to be capitalized). Draw a line to act as the Dynamic Lighting barrier for the door when closed (while still on the Token layer). Select all three objects. Type !DoorsLink (or set it as a macro and use that macro) The Open Door and Dynamic Lighting barrier will be moved to the GM layer and Dynamic Lighting layer, respectively. The open and closed doors will be renamed. This is how they are linked. DO NOT RENAME THE LINKED OBJECTS. Do this for each set of doors needed. Opening and Closing doors ------------------------- Once the objects are linked Select the door on the token layer Type !DoorOpenClose The door will open if it is closed, or it will close if it is opened. */ on("chat:message", function (msg) { "use strict"; var Parts = {}; if (msg.type !== "api") { return; } switch(msg.content.split(/\s+/).shift()) { case "!DoorsLink": //make sure three items are selected if (msg.selected.length > 3) { sendChat("Doors", "/w gm You have selected too many things, looking among them for what I need."); } else if (msg.selected.length < 3) { sendChat("Doors", "/w gm You have not selected enough things."); break; } //identify and get the ID for each each type of selected item _.each(msg.selected, function(obj) { var o = getObj(obj._type, obj._id); if(o) { if (o.get("_type") === "graphic" && o.get("name") === "DoorOpen" && !Parts.DoorOpen) { Parts.DoorOpen=o; } else if (o.get("type") === "graphic" && o.get("name") === "DoorClosed" && !Parts.DoorClosed) { Parts.DoorClosed = o; } else if (o.get("type") === "path" && !Parts.Path) { Parts.Path = o; } } }); if( Parts.DoorOpen && Parts.DoorClosed && Parts.Path) { Parts.DoorOpen.set({ name: Parts.Path.id +" "+Parts.DoorClosed.id, layer: "gmlayer" }); Parts.DoorClosed.set({ name: Parts.Path.id +" "+Parts.DoorOpen.id }); Parts.Path.set({ layer: "walls" }); } else { sendChat("Doors", "/w GM Couldn't fine required piece:<ul>" +(Parts.DoorOpen ? '' : '<li>Token named "DoorOpen".</li>') +(Parts.DoorClosed ? '' : '<li>Token named "DoorClosed".</li>') +(Parts.Path ? '' : '<li>Path for Dynamic Light Layer.</li>') +'</ul>' ); } break; case "!DoorOpenClose": _.chain(msg.selected) .map(function(o){ return getObj('graphic', o._id); }) .reject(_.isUndefined) .filter(function(o){ return 'objects' === o.get('layer'); }) .each(function(o){ var params=o.get('name').split(/\s+/), oDoor = getObj('graphic',params[1]), oPath = getObj('path',params[0]); if(oDoor && oPath) { o.set({ layer: 'gmlayer' }); oDoor.set({ layer: 'objects' }); oPath.set({ layer: ( 'walls' === oPath.get('layer') ? 'gmlayer' : 'walls') }); } else { sendChat('Doors','/w gm Missing components: <ul>' +(oDoor ? '' : '<li>GM Layer Door</li>') +(oPath ? '' : '<li>Dynamic Lighting Path</li>') +'</ul>'); } }); break; } });