diff --git a/src/components/auto-box-collider.js b/src/components/auto-box-collider.js
index 2d3d2f53bbbd4cbe18a3f9fd1f19603badd8f907..220ad92ed83ba506aa63f70dc2ee24e087ce61db 100644
--- a/src/components/auto-box-collider.js
+++ b/src/components/auto-box-collider.js
@@ -9,8 +9,11 @@ AFRAME.registerComponent("auto-box-collider", {
     this.el.addEventListener("model-loaded", this.onLoaded);
   },
 
-  onLoaded() {
+  remove() {
     this.el.removeEventListener("model-loaded", this.onLoaded);
+  },
+
+  onLoaded() {
     const rotation = this.el.object3D.rotation.clone();
     this.el.object3D.rotation.set(0, 0, 0);
     const { min, max } = new THREE.Box3().setFromObject(this.el.object3DMap.mesh);
diff --git a/src/components/auto-scale-cannon-physics-body.js b/src/components/auto-scale-cannon-physics-body.js
index e3ab60400e00f253e670736c2f94c44e301f4658..1633dffef17c70db520a7e8edb7ef3c819734970 100644
--- a/src/components/auto-scale-cannon-physics-body.js
+++ b/src/components/auto-scale-cannon-physics-body.js
@@ -4,6 +4,10 @@ function almostEquals(epsilon, u, v) {
 
 AFRAME.registerComponent("auto-scale-cannon-physics-body", {
   dependencies: ["body"],
+  schema: {
+    equalityEpsilon: { default: 0.001 },
+    debounceDelay: { default: 100 }
+  },
 
   init() {
     this.body = this.el.components["body"];
@@ -14,9 +18,9 @@ AFRAME.registerComponent("auto-scale-cannon-physics-body", {
   tick(t) {
     const scale = this.el.object3D.scale;
     // Note: This only checks if the LOCAL scale of the object3D changes.
-    if (!almostEquals(0.001, scale, this.prevScale)) {
+    if (!almostEquals(this.data.equalityEpsilon, scale, this.prevScale)) {
       this.prevScale.copy(scale);
-      this.nextUpdateTime = t + 100;
+      this.nextUpdateTime = t + this.data.debounceDelay;
     }
 
     if (this.nextUpdateTime > 0 && t > this.nextUpdateTime) {
diff --git a/src/components/image-plus.js b/src/components/image-plus.js
index c168789bbd807ba5acdf0400ea6fe3020a13ca93..744020534a6d9f5f6924ea12084572d4eb325109 100644
--- a/src/components/image-plus.js
+++ b/src/components/image-plus.js
@@ -118,7 +118,6 @@ AFRAME.registerComponent("image-plus", {
     const cacheItem = textureCache.get(url);
     cacheItem.count--;
     if (cacheItem.count <= 0) {
-      console.log("removing from cache");
       // Unload the video element to prevent it from continuing to play in the background
       if (texture.image instanceof HTMLVideoElement) {
         const video = texture.image;
@@ -179,7 +178,7 @@ AFRAME.registerComponent("image-plus", {
 
       const texture = new THREE.VideoTexture(videoEl);
       texture.minFilter = THREE.LinearFilter;
-      videoEl.addEventListener("loadedmetadata", () => resolve(texture));
+      videoEl.addEventListener("loadedmetadata", () => resolve(texture), { once: true });
       videoEl.onerror = reject;
 
       // If iOS and video is HLS, do some hacks.
@@ -225,13 +224,10 @@ AFRAME.registerComponent("image-plus", {
         if (url === "error") {
           texture = errorTexture;
         } else if (contentType === "image/gif") {
-          console.log("load gif", contentType);
           texture = await this.loadGIF(url);
         } else if (contentType.startsWith("image/")) {
-          console.log("load image", contentType);
           texture = await this.loadImage(url);
         } else if (contentType.startsWith("video")) {
-          console.log("load video", contentType);
           texture = await this.loadVideo(url);
         } else {
           throw new Error(`Unknown centent type: ${contentType}`);
diff --git a/src/components/input-configurator.js b/src/components/input-configurator.js
index 1609b20c7b163504d3dcc46390767bf14c91a09e..df36b38d8c4bb81a2f8fd98824cbd3ecf4ef7f15 100644
--- a/src/components/input-configurator.js
+++ b/src/components/input-configurator.js
@@ -69,7 +69,7 @@ AFRAME.registerComponent("input-configurator", {
     this.eventHandlers = [];
     this.actionEventHandler = null;
     if (this.lookOnMobile) {
-      this.lookOnMobile.el.removeComponent("look-on-mobile");
+      this.lookOnMobile.el.removeAttribute("look-on-mobile");
       this.lookOnMobile = null;
     }
     this.cursorRequiresManagement = false;
diff --git a/src/components/remove-networked-object-button.js b/src/components/remove-networked-object-button.js
index ff903435725101b1dff82b697be8e12d7832afcb..39ec27b754a2dfbb5476c9490ee40e3c30f12f79 100644
--- a/src/components/remove-networked-object-button.js
+++ b/src/components/remove-networked-object-button.js
@@ -1,9 +1,6 @@
 AFRAME.registerComponent("remove-networked-object-button", {
   init() {
     this.onClick = () => {
-      // const texture = this.targetEl.getObject3D("mesh").material.map;
-      // console.log(texture);
-      // texture.image.src = "";
       this.targetEl.parentNode.removeChild(this.targetEl);
     };
     NAF.utils.getNetworkedEntity(this.el).then(networkedEl => {
diff --git a/src/components/sticky-object.js b/src/components/sticky-object.js
index 31f84a3be97a815c8a3d6b1d5eb5b5ff06c5246a..d415779078f6a0acb2d6975170cde39cbd80cf47 100644
--- a/src/components/sticky-object.js
+++ b/src/components/sticky-object.js
@@ -79,20 +79,27 @@ AFRAME.registerComponent("sticky-object-zone", {
     this.bootImpulse = new CANNON.Vec3();
     this.bootImpulse.copy(dir);
 
-    this.el.addEventListener("collisions", e => {
-      e.detail.els.forEach(el => {
-        const stickyObject = el.components["sticky-object"];
-        if (!stickyObject) return;
-        this._setStuckObject(stickyObject);
-      });
-      if (this.stuckObject) {
-        e.detail.clearedEls.forEach(el => {
-          if (this.stuckObject && this.stuckObject.el === el) {
-            this._unstickObject();
-          }
-        });
-      }
+    this._onCollisions = this._onCollisions.bind(this);
+    this.el.addEventListener("collisions", this._onCollisions);
+  },
+
+  remove() {
+    this.el.removeEventListener("collisions", this._onCollisions);
+  },
+
+  _onCollisions(e) {
+    e.detail.els.forEach(el => {
+      const stickyObject = el.components["sticky-object"];
+      if (!stickyObject) return;
+      this._setStuckObject(stickyObject);
     });
+    if (this.stuckObject) {
+      e.detail.clearedEls.forEach(el => {
+        if (this.stuckObject && this.stuckObject.el === el) {
+          this._unstickObject();
+        }
+      });
+    }
   },
 
   _setStuckObject(stickyObject) {
diff --git a/src/hub.html b/src/hub.html
index 4c9f692a5ccffd1a5792a5b5a57df53966c270aa..f71396377f6f10cb02d076f08b430242c01522bf 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -33,7 +33,7 @@
     <a-scene
         renderer="antialias: true"
         networked-scene="adapter: janus; audio: true; debug: true; connectOnLoad: false;"
-        physics="gravity: -6; debug: true;"
+        physics="gravity: -6;"
         mute-mic="eventSrc: a-scene; toggleEvents: action_mute"
         freeze-controller="toggleEvent: action_freeze"
         personal-space-bubble="debug: false;"
@@ -409,39 +409,6 @@
             static-body="shape: none;"
         ></a-entity>
 
-        <a-entity
-            geometry="primitive: box;"
-            static-body="shape: box;"
-            collision-filter="collisionForces: false;"
-            physics-collider
-            sticky-object-zone
-            position="1.25 2 -5.9"
-            visible="false"
-            scale="1 1 0.5"
-        >
-        </a-entity>
-        <a-entity
-            geometry="primitive: box;"
-            static-body="shape: box;"
-            collision-filter="collisionForces: false;"
-            physics-collider
-            sticky-object-zone
-            position="0 2 -5.9"
-            visible="false"
-            scale="1 1 0.5"
-        >
-        </a-entity>
-        <a-entity
-            geometry="primitive: box;"
-            static-body="shape: box;"
-            collision-filter="collisionForces: false;"
-            physics-collider
-            sticky-object-zone
-            position="-1.25 2 -5.9"
-            visible="false"
-            scale="1 1 0.5"
-        >
-        </a-entity>
     </a-scene>
 
     <div id="ui-root"></div>
diff --git a/src/vendor/GLTFLoader.js b/src/vendor/GLTFLoader.js
index 906bb94655e3e63b02a473545715059ac4f220c2..754ae5d9460e80e176a928cc53ea75ab7a6f5212 100644
--- a/src/vendor/GLTFLoader.js
+++ b/src/vendor/GLTFLoader.js
@@ -7,6 +7,7 @@
  * @author Tony Parisi / http://www.tonyparisi.com/
  * @author Takahiro / https://github.com/takahirox
  * @author Don McCurdy / https://www.donmccurdy.com
+ * @author netpro2k / https://github.com/netpro2k
  */
 
  import { resolveFarsparkUrl } from "../utils/media-utils"