diff --git a/src/App.js b/src/App.js
new file mode 100644
index 0000000000000000000000000000000000000000..c542f439f903e0a4426d087cb33d69852b25944d
--- /dev/null
+++ b/src/App.js
@@ -0,0 +1,21 @@
+export class App {
+  constructor() {
+    this.scene = null;
+    this.quality = "low";
+  }
+
+  setQuality(quality) {
+    if (this.quality === quality) {
+      return false;
+    }
+
+    this.quality = quality;
+
+    if (this.scene) {
+      console.log("quality-changed", quality);
+      this.scene.dispatchEvent(new CustomEvent("quality-changed", { detail: quality }));
+    }
+
+    return true;
+  }
+}
diff --git a/src/assets/avatars/BotDefault_Avatar.glb b/src/assets/avatars/BotDefault_Avatar.glb
index 69b66c2954a64f17aa590790c50acfd0ee59c0c4..ccb77bf21362f3a5b2058f59eafd56fa17a55ec4 100644
Binary files a/src/assets/avatars/BotDefault_Avatar.glb and b/src/assets/avatars/BotDefault_Avatar.glb differ
diff --git a/src/components/hide-when-quality.js b/src/components/hide-when-quality.js
new file mode 100644
index 0000000000000000000000000000000000000000..e09d3ae90db3ce48e7afb815b5e0fcf22aa79fc3
--- /dev/null
+++ b/src/components/hide-when-quality.js
@@ -0,0 +1,23 @@
+AFRAME.registerComponent("hide-when-quality", {
+  schema: { type: "string", default: "low" },
+
+  init() {
+    this.onQualityChanged = this.onQualityChanged.bind(this);
+    this.el.sceneEl.addEventListener("quality-changed", this.onQualityChanged);
+  },
+
+  onQualityChanged(event) {
+    this.updateComponentState(event.detail);
+  },
+
+  update(oldData) {
+    if (this.data !== oldData) {
+      this.updateComponentState(window.APP.quality);
+    }
+  },
+
+  updateComponentState(quality) {
+    console.log(quality);
+    this.el.setAttribute("visible", quality !== this.data);
+  }
+});
diff --git a/src/elements/a-gltf-entity.js b/src/elements/a-gltf-entity.js
index 3903447c23354a6c23007fb837552c69b0220529..7caec327629a2d4059f0254a5a0438afe712b46b 100644
--- a/src/elements/a-gltf-entity.js
+++ b/src/elements/a-gltf-entity.js
@@ -1,7 +1,6 @@
 const GLTFCache = {};
 
 AFRAME.AGLTFEntity = {
-  quality: "low",
   defaultInflator(el, componentName, componentData) {
     if (AFRAME.components[componentName].multiple && Array.isArray(componentData)) {
       for (let i = 0; i < componentData.length; i++) {
@@ -160,9 +159,9 @@ AFRAME.registerElement("a-gltf-entity", {
           const highSrc = assetEl.getAttribute("high-src");
           const lowSrc = assetEl.getAttribute("low-src");
 
-          if (highSrc && AFRAME.AGLTFEntity.quality === "high") {
+          if (highSrc && window.APP.quality === "high") {
             src = highSrc;
-          } else if (lowSrc && AFRAME.AGLTFEntity.quality === "low") {
+          } else if (lowSrc && window.APP.quality === "low") {
             src = lowSrc;
           } else {
             src = fallbackSrc;
diff --git a/src/elements/a-progressive-asset.js b/src/elements/a-progressive-asset.js
index e6deeea752c62ae797934592ce26b94492182f86..a367e374aece30163bc73802ab8cf11950f28c1a 100644
--- a/src/elements/a-progressive-asset.js
+++ b/src/elements/a-progressive-asset.js
@@ -9,7 +9,12 @@ AFRAME.registerElement("a-progressive-asset", {
       value() {
         this.data = null;
         this.isAssetItem = true;
-        this.fileLoader = document.querySelector("a-assets").fileLoader;
+
+        if (!this.parentNode.fileLoader) {
+          throw new Error("a-progressive-asset must be the child of an a-assets element.");
+        }
+
+        this.fileLoader = this.parentNode.fileLoader;
       }
     },
 
@@ -22,9 +27,9 @@ AFRAME.registerElement("a-progressive-asset", {
 
         let src = fallbackSrc;
 
-        if (AFRAME.AGLTFEntity.quality === "high") {
+        if (window.APP.quality === "high") {
           src = highSrc;
-        } else if (AFRAME.AGLTFEntity.quality === "low") {
+        } else if (window.APP.quality === "low") {
           src = lowSrc;
         }
 
diff --git a/src/room.html b/src/room.html
index 55c37488ab8061981692d14b203cf24314b641b7..dd04fb42080c710b3f438b609a59b7b1cd4efcbb 100644
--- a/src/room.html
+++ b/src/room.html
@@ -155,7 +155,11 @@
         </a-entity>
 
         <!-- Lights -->
-        <a-entity light="type: directional; color: #F9FFCE; intensity: 0.6" position="0.002 5.231 -15.3"></a-entity>
+        <a-entity
+            hide-when-quality="low"
+            light="type: directional; color: #F9FFCE; intensity: 0.6"
+            position="0.002 5.231 -15.3"
+        ></a-entity>
 
         <!-- Environment -->
         <a-gltf-entity
diff --git a/src/room.js b/src/room.js
index eebb4ad0978a1a15bf5cb2548d171b9ae46a170f..df0ec4e9c5818e836fe86d9a2a689a16daa9d8b4 100644
--- a/src/room.js
+++ b/src/room.js
@@ -38,18 +38,23 @@ import "./components/water";
 import "./components/skybox";
 import "./components/layers";
 import "./components/spawn-controller";
+import "./components/hide-when-quality";
 
 import "./systems/personal-space-bubble";
 
 import "./gltf-component-mappings";
 
+import { App } from "./App";
+
+window.APP = new App();
+
 const qs = queryString.parse(location.search);
 const isMobile = AFRAME.utils.device.isMobile();
 
 if (qs.quality) {
-  AFRAME.AGLTFEntity.quality = qs.quality;
+  window.APP.quality = qs.quality;
 } else {
-  AFRAME.AGLTFEntity.quality = isMobile ? "low" : "high";
+  window.APP.quality = isMobile ? "low" : "high";
 }
 
 import "./elements/a-progressive-asset";
@@ -157,5 +162,9 @@ function onConnect() {
 }
 
 document.addEventListener("DOMContentLoaded", () => {
-  document.querySelector("a-scene").addEventListener("loaded", onSceneLoad);
+  const scene = document.querySelector("a-scene");
+
+  window.APP.scene = scene;
+
+  scene.addEventListener("loaded", onSceneLoad);
 });