diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml
index 4abaccfe2c..5c475f16dd 100644
--- a/interface/resources/qml/hifi/Pal.qml
+++ b/interface/resources/qml/hifi/Pal.qml
@@ -190,7 +190,7 @@ Item {
                 id: nameCard
                 // Properties
                 displayName: styleData.value
-                userName: model.userName
+                userName: model && model.userName
                 audioLevel: model.audioLevel
                 visible: !isCheckBox
                 // Size
@@ -204,15 +204,26 @@ Item {
             HifiControls.CheckBox {
                 visible: isCheckBox
                 anchors.centerIn: parent
+                checked: model[styleData.role]
                 boxSize: 24
                 onClicked: {
                     var newValue = !model[styleData.role]
                     var datum = userData[model.userIndex]
                     datum[styleData.role] = model[styleData.role] = newValue
-                    Users[styleData.role](model.sessionId)
-                    // Just for now, while we cannot undo things:
-                    userData.splice(model.userIndex, 1)
-                    sortModel()
+                    var key = styleData.role;
+                    if (!newValue) {
+                        key = 'un' + key;
+                    }
+                    if (styleData.role === 'ignore') {
+                        if (newValue) {
+                            ignored[datum.sessionId] = datum;
+                            console.log('fixme hrs adding to ignored', JSON.stringify(datum), 'at', datum.sessionId);
+                        } else {
+                            delete ignored[datum.sessionId];
+                        }
+                    }
+                    console.log('fixme hrs pal action', key, model.sessionId);
+                    Users[key](model.sessionId);
                 }
             }
         }
@@ -336,6 +347,7 @@ Item {
     property var userData: []
     property var myData: ({displayName: "", userName: "", audioLevel: 0.0}) // valid dummy until set
     property bool iAmAdmin: false
+    property var ignored: ({}); // FIXME: reset when changing domains
     function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml
         var i, data = optionalData || userData, length = data.length;
         for (var i = 0; i < length; i++) {
@@ -354,6 +366,16 @@ Item {
             myData = data[myIndex];
             data.splice(myIndex, 1);
             userData = data;
+            var ignoredID, index;
+            for (ignoredID in ignored) {
+                index = findSessionIndex(ignoredID);
+                console.log('fixme hrs adding back ignored', ignoredID, index, JSON.stringify(ignored[ignoredID]));
+                if (-1 === index) { // Add back any missing ignored, because they sometimes take a moment to show up.
+                    userData.push(ignored[ignoredID]);
+                } else {            // Mark existing ignored.
+                    userData[index].ignored = true;
+                }
+            }
             sortModel();
             break;
         case 'select':
diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp
index dc5b6233aa..bcd6ef7527 100644
--- a/interface/src/avatar/Avatar.cpp
+++ b/interface/src/avatar/Avatar.cpp
@@ -292,7 +292,15 @@ void Avatar::updateAvatarEntities() {
     }
 }
 
+void Avatar::setShouldDie() {
+    // This will cause the avatar to be shrunk away and removed (the actual Avatar gets removed), but then it comes back.
+    _owningAvatarMixer.clear();
 
+    // This removes the avatar from physics and makes it shrink away, but does not actualy remvoe Avatar from Avatar Manager.
+    // FIXME hrs remove, unless it can be made to work cleanly.
+    // (In which case, this could be on AvatarList/AvatarManager instead, and consider moving pal.js usage to Pal.qml, and removing (un)ignoredNode signalling.)
+    //DependencyManager::get<AvatarManager>()->handleRemovedAvatar(AvatarSharedPointer(this), AvatarIgnored);
+}
 
 void Avatar::simulate(float deltaTime) {
     PerformanceTimer perfTimer("simulate");
diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h
index 784f380028..3478b3ed21 100644
--- a/interface/src/avatar/Avatar.h
+++ b/interface/src/avatar/Avatar.h
@@ -178,6 +178,8 @@ public:
     glm::vec3 getUncachedRightPalmPosition() const;
     glm::quat getUncachedRightPalmRotation() const;
 
+    Q_INVOKABLE void setShouldDie();
+
 public slots:
 
     // FIXME - these should be migrated to use Pose data instead
diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp
index c5222641ff..25006d52a0 100644
--- a/interface/src/avatar/AvatarManager.cpp
+++ b/interface/src/avatar/AvatarManager.cpp
@@ -198,6 +198,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
         if (avatar->getTargetScale() <= MIN_FADE_SCALE) {
             avatar->removeFromScene(*fadingIterator, scene, pendingChanges);
             // only remove from _avatarFades if we're sure its motionState has been removed from PhysicsEngine
+            qDebug() << "fixme hrs at minimum fade scale" << _motionStatesToRemoveFromPhysics.empty();
             if (_motionStatesToRemoveFromPhysics.empty()) {
                 fadingIterator = _avatarFades.erase(fadingIterator);
             } else {
diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h
index f38796ca08..a423e34f8f 100644
--- a/interface/src/avatar/AvatarManager.h
+++ b/interface/src/avatar/AvatarManager.h
@@ -93,7 +93,6 @@ private:
     // virtual overrides
     virtual AvatarSharedPointer newSharedAvatar() override;
     virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
-
     virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
 
     QVector<AvatarSharedPointer> _avatarFades;
diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp
index b118423236..e736bf2a84 100644
--- a/libraries/script-engine/src/UsersScriptingInterface.cpp
+++ b/libraries/script-engine/src/UsersScriptingInterface.cpp
@@ -19,6 +19,8 @@ UsersScriptingInterface::UsersScriptingInterface() {
     connect(nodeList.data(), &LimitedNodeList::canKickChanged, this, &UsersScriptingInterface::canKickChanged);
     connect(nodeList.data(), &NodeList::ignoreRadiusEnabledChanged, this, &UsersScriptingInterface::ignoreRadiusEnabledChanged);
     connect(nodeList.data(), &NodeList::usernameFromIDReply, this, &UsersScriptingInterface::usernameFromIDReply);
+    connect(nodeList.data(), &NodeList::ignoredNode, this, &UsersScriptingInterface::ignoredNode);
+    connect(nodeList.data(), &NodeList::unignoredNode, this, &UsersScriptingInterface::unignoredNode);
 }
 
 void UsersScriptingInterface::ignore(const QUuid& nodeID) {
diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h
index c8866376da..394e006451 100644
--- a/libraries/script-engine/src/UsersScriptingInterface.h
+++ b/libraries/script-engine/src/UsersScriptingInterface.h
@@ -95,6 +95,8 @@ public slots:
 signals:
     void canKickChanged(bool canKick);
     void ignoreRadiusEnabledChanged(bool isEnabled);
+    void ignoredNode(const QUuid& nodeID);
+    void unignoredNode(const QUuid& nodeID);
 
     /**jsdoc
     * Notifies scripts that another user has entered the ignore radius
diff --git a/scripts/system/pal.js b/scripts/system/pal.js
index 77f939d2c5..7e25496537 100644
--- a/scripts/system/pal.js
+++ b/scripts/system/pal.js
@@ -329,6 +329,12 @@ pal.visibleChanged.connect(onVisibleChanged);
 pal.closed.connect(off);
 Users.usernameFromIDReply.connect(usernameFromIDReply);
 
+function onIgnore(sessionId) { // make it go away in the usual way, since we'll still get data keeping it live
+    // Why doesn't this work from .qml? (crashes)
+    AvatarList.getAvatar(sessionId).setShouldDie();
+}
+Users.ignoredNode.connect(onIgnore);
+
 //
 // Cleanup.
 //
@@ -338,6 +344,7 @@ Script.scriptEnding.connect(function () {
     pal.visibleChanged.disconnect(onVisibleChanged);
     pal.closed.disconnect(off);
     Users.usernameFromIDReply.disconnect(usernameFromIDReply);
+    Users.ignoredNode.disconnect(onIgnore);
     off();
 });