diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml
index d52dd3f3d7..7dbadc59f4 100644
--- a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml
+++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml
@@ -9,6 +9,7 @@
 //
 
 import QtQuick 2.10
+import QtQuick.Layouts 1.3
 import "../simplifiedConstants" as SimplifiedConstants
 import "../simplifiedControls" as SimplifiedControls
 import "./components" as AvatarAppComponents
@@ -79,7 +80,11 @@ Rectangle {
                 errorText.text = "There was a problem while retrieving your inventory. " +
                     "Please try closing and re-opening the Avatar app.\n\nInventory status: " + result.status + "\nMessage: " + result.message;
             } else if (result.data && result.data.assets && result.data.assets.length === 0 && avatarAppInventoryModel.count === 0) {
-                errorText.text = "You have not created any avatars yet! Create an avatar with the Avatar Creator, then close and re-open the Avatar App."
+                emptyInventoryContainer.visible = true;
+            }
+
+            if (Settings.getValue("simplifiedUI/debugFTUE", 0) === 4) {
+                emptyInventoryContainer.visible = true;
             }
 
             avatarAppInventoryModel.handlePage(result.status !== "success" && result.message, result);
@@ -140,8 +145,95 @@ Rectangle {
         anchors.rightMargin: 24
     }
 
+
+    Item {
+        id: emptyInventoryContainer
+        visible: false
+        anchors.top: displayNameHeader.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.bottom: parent.bottom
+
+        Flickable {
+            id: emptyInventoryFlickable
+            anchors.fill: parent
+            contentWidth: parent.width
+            contentHeight: emptyInventoryLayout.height
+            clip: true
+
+            ColumnLayout {
+                id: emptyInventoryLayout
+                anchors.top: parent.top
+                anchors.left: parent.left
+                anchors.leftMargin: 26
+                anchors.right: parent.right
+                anchors.rightMargin: 26
+                spacing: 0
+
+                HifiStylesUit.GraphikSemiBold {
+                    text: "Stand out from the crowd!"
+                    Layout.preferredWidth: parent.width
+                    Layout.preferredHeight: paintedHeight
+                    Layout.topMargin: 16
+                    size: 28
+                    color: simplifiedUI.colors.text.white
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.Wrap
+                }
+
+                HifiStylesUit.GraphikRegular {
+                    text: "Create your custom avatar."
+                    Layout.preferredWidth: parent.width
+                    Layout.preferredHeight: paintedHeight
+                    Layout.topMargin: 2
+                    size: 18
+                    wrapMode: Text.Wrap
+                    color: simplifiedUI.colors.text.white
+                    horizontalAlignment: Text.AlignHCenter
+                }
+
+                Image {
+                    id: avatarImage;
+                    source: "images/avatarProfilePic.png"
+                    Layout.preferredWidth: parent.width
+                    Layout.preferredHeight: 450
+                    Layout.alignment: Qt.AlignHCenter
+                    mipmap: true
+                    fillMode: Image.PreserveAspectFit
+                }
+
+                Image {
+                    source: "images/qrCode.jpg"
+                    Layout.preferredWidth: 190
+                    Layout.preferredHeight: 190
+                    Layout.alignment: Qt.AlignHCenter
+                    Layout.topMargin: -160
+                    mipmap: true
+                    fillMode: Image.PreserveAspectFit
+                }
+
+                HifiStylesUit.GraphikSemiBold {
+                    text: "Scan for Mobile App"
+                    Layout.preferredWidth: parent.width
+                    Layout.preferredHeight: paintedHeight
+                    Layout.topMargin: 12
+                    size: 28
+                    color: simplifiedUI.colors.text.white
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.Wrap
+                }
+            }
+        }
+
+        SimplifiedControls.VerticalScrollBar {
+            parent: emptyInventoryFlickable
+        }
+    }
+
+
     Item {
         id: avatarInfoTextContainer
+        visible: !emptyInventoryContainer.visible
         width: parent.implicitWidth
         height: childrenRect.height
         anchors.top: displayNameHeader.bottom
@@ -164,7 +256,7 @@ Rectangle {
             id: yourAvatarsSubtitle
             text: "These are the avatars that you've created and uploaded via the Avatar Creator."
             width: parent.width
-            wrapMode: Text.WordWrap
+            wrapMode: Text.Wrap
             anchors.top: yourAvatarsTitle.bottom
             anchors.topMargin: 6
             verticalAlignment: TextInput.AlignVCenter
@@ -208,9 +300,10 @@ Rectangle {
         anchors.left: parent.left
         anchors.right: parent.right
         anchors.bottom: parent.bottom
+        visible: !emptyInventoryContainer.visible
             
         AnimatedImage {
-            visible: !inventoryContentsList.visible && !errorText.visible
+            visible: !(inventoryContentsList.visible || errorText.visible)
             anchors.centerIn: parent
             width: 72
             height: width
@@ -271,6 +364,8 @@ Rectangle {
                 return;
             }
         }
+        
+        root.avatarPreviewUrl = "../../images/defaultAvatar.svg";
     }
 
     function fromScript(message) {
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/avatarProfilePic.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/avatarProfilePic.png
new file mode 100644
index 0000000000..b59ebb3085
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/avatarProfilePic.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/hero.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/hero.png
new file mode 100644
index 0000000000..15c358e024
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/hero.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg
new file mode 100644
index 0000000000..0674781c45
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Blue.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Blue.png
new file mode 100644
index 0000000000..210d37acb6
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Blue.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Cyan.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Cyan.png
new file mode 100644
index 0000000000..726e1c8a69
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Cyan.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Green.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Green.png
new file mode 100644
index 0000000000..6db55816dc
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Green.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Magenta.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Magenta.png
new file mode 100644
index 0000000000..f01622dcd0
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Magenta.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Red.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Red.png
new file mode 100644
index 0000000000..1e308d7f1f
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Red.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Yellow.png b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Yellow.png
new file mode 100644
index 0000000000..b123f358c0
Binary files /dev/null and b/interface/resources/qml/hifi/simplifiedUI/avatarApp/images/simplifiedAvatar_Yellow.png differ
diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml
index 4919077dc3..65a5eb0c80 100644
--- a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml
+++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml
@@ -54,8 +54,8 @@ Rectangle {
 
             if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) &&
                 topBarInventoryModel.count > 0) {
-                Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
-                MyAvatar.useFullAvatarURL = topBarInventoryModel.get(0).download_url;
+                Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", true);
+                MyAvatar.useFullAvatarURL(topBarInventoryModel.get(0).download_url);
             }
         }
     }
@@ -71,7 +71,7 @@ Rectangle {
             if (isLoggedIn) {
                 Commerce.getWalletStatus();
             } else {
-                // Show some error to the user
+                // Show some error to the user in the UI?
             }
         }
 
@@ -113,12 +113,68 @@ Rectangle {
                 topBarInventoryModel.getNextPage();
             } else {
                 inventoryFullyReceived = true;
+                var scriptExecutionCount = Settings.getValue("simplifiedUI/SUIScriptExecutionCount");
+                var currentAvatarURL = MyAvatar.skeletonModelURL;
+                var currentAvatarURLContainsDefaultAvatar = currentAvatarURL.indexOf("defaultAvatar") > -1;
+                var currentAvatarURLContainsFST = currentAvatarURL.indexOf("fst") > -1;
+                var currentAvatarURLContainsSimplifiedAvatar = currentAvatarURL.indexOf("simplifiedAvatar") > -1;
+                var alreadyAutoSelectedAvatarFromInventory = Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", false);
+                var userHasValidAvatarInInventory = topBarInventoryModel.count > 0 && 
+                    topBarInventoryModel.get(0).download_url.indexOf(".fst") > -1;
+                var simplifiedAvatarPrefix = "https://content.highfidelity.com/Experiences/Releases/simplifiedUI/simplifiedFTUE/avatars/simplifiedAvatar_";
+                var simplifiedAvatarColors = ["Blue", "Cyan", "Green", "Magenta", "Red"];
+                var simplifiedAvatarSuffix = "/avatar.fst";
 
-                // If we have an avatar in our inventory AND we haven't already auto-selected an avatar...
-                if ((!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) ||
-                    MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && topBarInventoryModel.count > 0) {
-                    Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
-                    MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
+                // Use `Settings.setValue("simplifiedUI/debugFTUE", 0);` to turn off FTUE Debug Mode.
+                // Use `Settings.setValue("simplifiedUI/debugFTUE", 1);` to debug FTUE Screen 1.
+                // Use `Settings.setValue("simplifiedUI/debugFTUE", 2);` to debug FTUE Screen 2.
+                // Use `Settings.setValue("simplifiedUI/debugFTUE", 3);` to debug FTUE Screen 3.
+                // Use `Settings.setValue("simplifiedUI/debugFTUE", 4);` to force the UI to show what would happen if the user had an empty Inventory.
+
+                var debugFTUE = Settings.getValue("simplifiedUI/debugFTUE", 0);
+                if (debugFTUE === 1 || debugFTUE === 2) {
+                    scriptExecutionCount = 1;
+                    currentAvatarURLContainsDefaultAvatar = true;
+                    if (debugFTUE === 1) {
+                        userHasValidAvatarInInventory = false;
+                        currentAvatarURLContainsSimplifiedAvatar = false;
+                    }
+                } else if (debugFTUE === 3) {
+                    scriptExecutionCount = 2;
+                    currentAvatarURLContainsDefaultAvatar = false;
+                    currentAvatarURLContainsSimplifiedAvatar = true;
+                }
+
+                // If we have never auto-selected and the user is still using a default avatar or if the current avatar is not valid (fst), or if 
+                // the current avatar is the old default (Woody), use top avatar from inventory or one of the new defaults.
+
+                // If the current avatar URL is invalid, OR the user is using the "default avatar" (Woody)...
+                if (!currentAvatarURLContainsFST || currentAvatarURLContainsDefaultAvatar) {
+                    // If the user has a valid avatar in their inventory...
+                    if (userHasValidAvatarInInventory) {
+                        // ...use the first avatar in the user's inventory.
+                        MyAvatar.useFullAvatarURL(topBarInventoryModel.get(0).download_url);
+                        Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", true);
+                    // Else if the user isn't wearing a "Simplified Avatar"
+                    } else if (!currentAvatarURLContainsSimplifiedAvatar) {
+                        // ...assign to the user a new "Simplified Avatar" (i.e. a simple avatar of random color)
+                        var avatarColor = simplifiedAvatarColors[Math.floor(Math.random() * simplifiedAvatarColors.length)];
+                        var simplifiedAvatarModelURL = simplifiedAvatarPrefix + avatarColor + simplifiedAvatarSuffix;
+                        MyAvatar.useFullAvatarURL(simplifiedAvatarModelURL);
+                        currentAvatarURLContainsSimplifiedAvatar = true;
+                    }
+                }
+
+                if (scriptExecutionCount === 1) {
+                    sendToScript({
+                        "source": "SimplifiedTopBar.qml",
+                        "method": "displayInitialLaunchWindow"
+                    });
+                } else if (scriptExecutionCount === 2 && currentAvatarURLContainsSimplifiedAvatar) {
+                    sendToScript({
+                        "source": "SimplifiedTopBar.qml",
+                        "method": "displaySecondLaunchWindow"
+                    });
                 }
             }
         }
@@ -556,7 +612,7 @@ Rectangle {
     }
 
 
-    function updatePreviewUrl() {
+    function updatePreviewUrl() {        
         var previewUrl = "";
         var downloadUrl = "";
         for (var i = 0; i < topBarInventoryModel.count; ++i) {
@@ -570,6 +626,8 @@ Rectangle {
                 return;
             }
         }
+        
+        avatarButtonImage.source = "../images/defaultAvatar.svg";
     }
 
 
diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp
index 95d3bae332..32b5eb768d 100644
--- a/interface/src/scripting/DesktopScriptingInterface.cpp
+++ b/interface/src/scripting/DesktopScriptingInterface.cpp
@@ -52,6 +52,21 @@ static const QVariantMap DOCK_AREA {
     { "RIGHT", DockArea::RIGHT }
 };
 
+/**jsdoc
+ * The possible "relative position anchors" of an <code>InteractiveWindow</code>. Used when defining the `relativePosition` property of an `InteractiveWindow`.
+ * @typedef {object} InteractiveWindow.RelativePositionAnchors
+ * @property {InteractiveWindow.RelativePositionAnchor} TOP_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top left of the Interface window.
+ * @property {InteractiveWindow.RelativePositionAnchor} TOP_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top right of the Interface window.
+ * @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom right of the Interface window.
+ * @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom left of the Interface window.
+ */
+static const QVariantMap RELATIVE_POSITION_ANCHOR {
+    { "TOP_LEFT", RelativePositionAnchor::TOP_LEFT },
+    { "TOP_RIGHT", RelativePositionAnchor::TOP_RIGHT },
+    { "BOTTOM_RIGHT", RelativePositionAnchor::BOTTOM_RIGHT },
+    { "BOTTOM_LEFT", RelativePositionAnchor::BOTTOM_LEFT }
+};
+
 DesktopScriptingInterface::DesktopScriptingInterface(QObject* parent, bool restricted) 
     : QObject(parent), _restricted(restricted) { }
 
@@ -99,6 +114,10 @@ QVariantMap DesktopScriptingInterface::getDockArea() {
     return DOCK_AREA;
 }
 
+QVariantMap DesktopScriptingInterface::getRelativePositionAnchor() {
+    return RELATIVE_POSITION_ANCHOR;
+}
+
 void DesktopScriptingInterface::setHUDAlpha(float alpha) {
     qApp->getApplicationCompositor().setAlpha(alpha);
 }
diff --git a/interface/src/scripting/DesktopScriptingInterface.h b/interface/src/scripting/DesktopScriptingInterface.h
index e562a32543..c25f382891 100644
--- a/interface/src/scripting/DesktopScriptingInterface.h
+++ b/interface/src/scripting/DesktopScriptingInterface.h
@@ -42,6 +42,9 @@
  * @property {InteractiveWindow.DockAreas} DockArea - The possible docking locations of an {@link InteractiveWindow}: top, 
  *     bottom, left, or right of the Interface window. 
  *     <em>Read-only.</em>
+ * @property {InteractiveWindow.RelativePositionAnchors} RelativePositionAnchor - The possible "relative position anchors" for an {@link InteractiveWindow}: top left, 
+ *     top right, bottom right, or bottom left of the Interface window. 
+ *     <em>Read-only.</em>
  */
 class DesktopScriptingInterface : public QObject, public Dependency {
     Q_OBJECT
@@ -50,6 +53,7 @@ class DesktopScriptingInterface : public QObject, public Dependency {
 
     Q_PROPERTY(QVariantMap PresentationMode READ getPresentationMode CONSTANT FINAL)
     Q_PROPERTY(QVariantMap DockArea READ getDockArea CONSTANT FINAL)
+    Q_PROPERTY(QVariantMap RelativePositionAnchor READ getRelativePositionAnchor CONSTANT FINAL)
     Q_PROPERTY(int ALWAYS_ON_TOP READ flagAlwaysOnTop CONSTANT FINAL)
     Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
 
@@ -106,7 +110,7 @@ private:
     Q_INVOKABLE InteractiveWindowPointer createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread);
 
     static QVariantMap getDockArea();
-
+    static QVariantMap getRelativePositionAnchor();
     Q_INVOKABLE static QVariantMap getPresentationMode();
     const bool _restricted;
 };
diff --git a/interface/src/ui/InteractiveWindow.cpp b/interface/src/ui/InteractiveWindow.cpp
index e63c392a47..b7140b4009 100644
--- a/interface/src/ui/InteractiveWindow.cpp
+++ b/interface/src/ui/InteractiveWindow.cpp
@@ -39,6 +39,9 @@ static const char* const ADDITIONAL_FLAGS_PROPERTY = "additionalFlags";
 static const char* const OVERRIDE_FLAGS_PROPERTY = "overrideFlags";
 static const char* const SOURCE_PROPERTY = "source";
 static const char* const TITLE_PROPERTY = "title";
+static const char* const RELATIVE_POSITION_ANCHOR_PROPERTY = "relativePositionAnchor";
+static const char* const RELATIVE_POSITION_PROPERTY = "relativePosition";
+static const char* const IS_FULL_SCREEN_WINDOW = "isFullScreenWindow";
 static const char* const POSITION_PROPERTY = "position";
 static const char* const INTERACTIVE_WINDOW_POSITION_PROPERTY = "interactiveWindowPosition";
 static const char* const SIZE_PROPERTY = "size";
@@ -112,6 +115,14 @@ void InteractiveWindow::forwardKeyReleaseEvent(int key, int modifiers) {
     QCoreApplication::postEvent(QCoreApplication::instance(), event);
 }
 
+void InteractiveWindow::onMainWindowGeometryChanged(QRect geometry) {
+    if (_isFullScreenWindow) {
+        repositionAndResizeFullScreenWindow();
+    } else {
+        setPositionUsingRelativePositionAndAnchor(geometry);
+    }
+}
+
 void InteractiveWindow::emitMainWindowResizeEvent() {
     emit qApp->getWindow()->windowGeometryChanged(qApp->getWindow()->geometry());
 }
@@ -184,22 +195,32 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
          */
         if (nativeWindowInfo.contains(DOCK_AREA_PROPERTY)) {
             DockArea dockedArea = (DockArea) nativeWindowInfo[DOCK_AREA_PROPERTY].toInt();
+            int tempWidth = 0;
+            int tempHeight = 0;
             switch (dockedArea) {
                 case DockArea::TOP:
                     dockArea = Qt::TopDockWidgetArea;
-                    _dockWidget->setFixedHeight(windowSize.height());
+                    tempHeight = windowSize.height();
+                    _dockWidget->setFixedHeight(tempHeight);
+                    qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(0, -tempHeight));
                     break;
                 case DockArea::BOTTOM:
                     dockArea = Qt::BottomDockWidgetArea;
-                    _dockWidget->setFixedHeight(windowSize.height());
+                    tempHeight = windowSize.height();
+                    _dockWidget->setFixedHeight(tempHeight);
+                    qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(0, tempHeight));
                     break;
                 case DockArea::LEFT:
                     dockArea = Qt::LeftDockWidgetArea;
-                    _dockWidget->setFixedWidth(windowSize.width());
+                    tempWidth = windowSize.width();
+                    _dockWidget->setFixedWidth(tempWidth);
+                    qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(-tempWidth, 0));
                     break;
                 case DockArea::RIGHT:
                     dockArea = Qt::RightDockWidgetArea;
-                    _dockWidget->setFixedWidth(windowSize.width());
+                    tempWidth = windowSize.width();
+                    _dockWidget->setFixedWidth(tempWidth);
+                    qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(tempWidth, 0));
                     break;
 
                 default:
@@ -255,6 +276,9 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
             if (properties.contains(TITLE_PROPERTY)) {
                 object->setProperty(TITLE_PROPERTY, properties[TITLE_PROPERTY].toString());
             }
+            if (properties.contains(VISIBLE_PROPERTY)) {
+                object->setProperty(VISIBLE_PROPERTY, properties[INTERACTIVE_WINDOW_VISIBLE_PROPERTY].toBool());
+            }
             if (properties.contains(SIZE_PROPERTY)) {
                 const auto size = vec2FromVariant(properties[SIZE_PROPERTY]);
                 object->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(size.x, size.y));
@@ -263,8 +287,21 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
                 const auto position = vec2FromVariant(properties[POSITION_PROPERTY]);
                 object->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(position.x, position.y));
             }
-            if (properties.contains(VISIBLE_PROPERTY)) {
-                object->setProperty(VISIBLE_PROPERTY, properties[INTERACTIVE_WINDOW_VISIBLE_PROPERTY].toBool());
+            if (properties.contains(RELATIVE_POSITION_ANCHOR_PROPERTY)) {
+                _relativePositionAnchor = static_cast<RelativePositionAnchor>(properties[RELATIVE_POSITION_ANCHOR_PROPERTY].toInt());
+            }
+            if (properties.contains(RELATIVE_POSITION_PROPERTY)) {
+                _relativePosition = vec2FromVariant(properties[RELATIVE_POSITION_PROPERTY]);
+                setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
+            }
+            if (properties.contains(IS_FULL_SCREEN_WINDOW)) {
+                _isFullScreenWindow = properties[IS_FULL_SCREEN_WINDOW].toBool();
+            }
+
+            if (_isFullScreenWindow) {
+                QRect geo = qApp->getWindow()->geometry();
+                object->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(geo.x(), geo.y()));
+                object->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(geo.width(), geo.height()));
             }
 
             // The qmlToScript method handles the thread-safety of this call. Because the QVariant argument
@@ -288,6 +325,8 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
             connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection);
             connect(object, SIGNAL(presentationModeChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection);
 #endif
+            
+            connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &InteractiveWindow::onMainWindowGeometryChanged, Qt::QueuedConnection);
 
             QUrl sourceURL{ sourceUrl };
             // If the passed URL doesn't correspond to a known scheme, assume it's a local file path
@@ -414,6 +453,68 @@ void InteractiveWindow::setPosition(const glm::vec2& position) {
     }
 }
 
+RelativePositionAnchor InteractiveWindow::getRelativePositionAnchor() const {
+    return _relativePositionAnchor;
+}
+
+void InteractiveWindow::setRelativePositionAnchor(const RelativePositionAnchor& relativePositionAnchor) {
+    _relativePositionAnchor = relativePositionAnchor;
+    setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
+}
+
+glm::vec2 InteractiveWindow::getRelativePosition() const {
+    return _relativePosition;
+}
+
+void InteractiveWindow::setRelativePosition(const glm::vec2& relativePosition) {    
+    _relativePosition = relativePosition;
+    setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
+}
+
+void InteractiveWindow::setPositionUsingRelativePositionAndAnchor(const QRect& mainWindowGeometry) {
+    RelativePositionAnchor relativePositionAnchor = getRelativePositionAnchor();
+    glm::vec2 relativePosition = getRelativePosition();
+
+    glm::vec2 newPosition;
+
+    switch (relativePositionAnchor) {
+        case RelativePositionAnchor::TOP_LEFT:
+            newPosition.x = mainWindowGeometry.x() + relativePosition.x;
+            newPosition.y = mainWindowGeometry.y() + relativePosition.y;
+            break;
+        case RelativePositionAnchor::TOP_RIGHT:
+            newPosition.x = mainWindowGeometry.x() + mainWindowGeometry.width() - relativePosition.x;
+            newPosition.y = mainWindowGeometry.y() + relativePosition.y;
+            break;
+        case RelativePositionAnchor::BOTTOM_RIGHT:
+            newPosition.x = mainWindowGeometry.x() + mainWindowGeometry.width() - relativePosition.x;
+            newPosition.y = mainWindowGeometry.y() + mainWindowGeometry.height() - relativePosition.y;
+            break;
+        case RelativePositionAnchor::BOTTOM_LEFT:
+            newPosition.x = mainWindowGeometry.x() + relativePosition.x;
+            newPosition.y = mainWindowGeometry.y() + mainWindowGeometry.height() - relativePosition.y;
+            break;
+    }
+
+    // Make sure we include the dimensions of the docked widget!
+    QSize dockedWidgetRelativePositionOffset = qApp->getWindow()->getDockedWidgetRelativePositionOffset();
+    newPosition.x = newPosition.x + dockedWidgetRelativePositionOffset.width();
+    newPosition.y = newPosition.y + dockedWidgetRelativePositionOffset.height();
+
+    if (_qmlWindowProxy) {
+        QMetaObject::invokeMethod(_qmlWindowProxy.get(), "writeProperty", Q_ARG(QString, INTERACTIVE_WINDOW_POSITION_PROPERTY),
+            Q_ARG(QVariant, QPointF(newPosition.x, newPosition.y)));
+    }
+    setPosition(newPosition);
+}
+
+void InteractiveWindow::repositionAndResizeFullScreenWindow() {
+    QRect windowGeometry = qApp->getWindow()->geometry();
+
+    setPosition(glm::vec2(windowGeometry.x(), windowGeometry.y()));
+    setSize(glm::vec2(windowGeometry.width(), windowGeometry.height()));
+}
+
 glm::vec2 InteractiveWindow::getSize() const {
     if (!_qmlWindowProxy) {
         return {};
diff --git a/interface/src/ui/InteractiveWindow.h b/interface/src/ui/InteractiveWindow.h
index ba53684173..d25c3d7ec2 100644
--- a/interface/src/ui/InteractiveWindow.h
+++ b/interface/src/ui/InteractiveWindow.h
@@ -89,6 +89,14 @@ namespace InteractiveWindowEnums {
         RIGHT
     };
     Q_ENUM_NS(DockArea);
+
+    enum RelativePositionAnchor {
+        TOP_LEFT,
+        TOP_RIGHT,
+        BOTTOM_RIGHT,
+        BOTTOM_LEFT
+    };
+    Q_ENUM_NS(RelativePositionAnchor);
 }
 
 using namespace InteractiveWindowEnums;
@@ -121,6 +129,8 @@ class InteractiveWindow : public QObject {
 
     Q_PROPERTY(QString title READ getTitle WRITE setTitle)
     Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
+    Q_PROPERTY(RelativePositionAnchor relativePositionAnchor READ getRelativePositionAnchor WRITE setRelativePositionAnchor)
+    Q_PROPERTY(glm::vec2 relativePosition READ getRelativePosition WRITE setRelativePosition)
     Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
     Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
     Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
@@ -136,6 +146,21 @@ private:
 
     Q_INVOKABLE glm::vec2 getPosition() const;
     Q_INVOKABLE void setPosition(const glm::vec2& position);
+    
+    RelativePositionAnchor _relativePositionAnchor{ RelativePositionAnchor::TOP_LEFT };
+    Q_INVOKABLE RelativePositionAnchor getRelativePositionAnchor() const;
+    Q_INVOKABLE void setRelativePositionAnchor(const RelativePositionAnchor& position);
+
+    // This "relative position" is relative to the "relative position anchor" and excludes the window frame.
+    // This position will ALWAYS include the geometry of a docked widget, if one is present.
+    glm::vec2 _relativePosition{ 0.0f, 0.0f };
+    Q_INVOKABLE glm::vec2 getRelativePosition() const;
+    Q_INVOKABLE void setRelativePosition(const glm::vec2& position);
+
+    Q_INVOKABLE void setPositionUsingRelativePositionAndAnchor(const QRect& mainWindowGeometry);
+
+    bool _isFullScreenWindow{ false };
+    Q_INVOKABLE void repositionAndResizeFullScreenWindow();
 
     Q_INVOKABLE glm::vec2 getSize() const;
     Q_INVOKABLE void setSize(const glm::vec2& size);
@@ -320,6 +345,7 @@ protected slots:
     void forwardKeyPressEvent(int key, int modifiers);
     void forwardKeyReleaseEvent(int key, int modifiers);
     void emitMainWindowResizeEvent();
+    void onMainWindowGeometryChanged(QRect geometry);
 
 private:
     std::shared_ptr<QmlWindowProxy> _qmlWindowProxy;
diff --git a/libraries/ui/src/MainWindow.h b/libraries/ui/src/MainWindow.h
index 543f8ce9af..b37ac2ec1b 100644
--- a/libraries/ui/src/MainWindow.h
+++ b/libraries/ui/src/MainWindow.h
@@ -24,6 +24,10 @@ public:
     ~MainWindow();
 
     static QWindow* findMainWindow();
+
+    // This offset is used for positioning children window relative to the main window.
+    void setDockedWidgetRelativePositionOffset(const QSize& newOffset) { _dockedWidgetRelativePositionOffset.setWidth(newOffset.width()); _dockedWidgetRelativePositionOffset.setHeight(newOffset.height()); }
+    QSize getDockedWidgetRelativePositionOffset() { return _dockedWidgetRelativePositionOffset; }
 public slots:
     void restoreGeometry();
     void saveGeometry();
@@ -46,6 +50,7 @@ protected:
 private:
     Setting::Handle<QRect> _windowGeometry;
     Setting::Handle<int> _windowState;
+    QSize _dockedWidgetRelativePositionOffset{ 0, 0 };
 };
 
 #endif /* defined(__hifi__MainWindow__) */
diff --git a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js
index 8633fe8870..d7d6279e10 100644
--- a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js
+++ b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js
@@ -444,17 +444,9 @@ function updateEmoteIndicatorIcon(iconURL) {
 }
 
 
-function onGeometryChanged(rect) {
-    updateEmoteAppBarPosition();
-}
-
-
 function onWindowMinimizedChanged(isMinimized) {
-    if (isMinimized) {
-        handleEmoteIndicatorVisibleChanged(false);
-    } else if (!HMD.active) {
-        handleEmoteIndicatorVisibleChanged(true);
-    }
+    isWindowMinimized = isMinimized;
+    maybeChangeEmoteIndicatorVisibility(!isMinimized);
 }
 
 
@@ -539,10 +531,11 @@ function showEmoteAppBar() {
             x: EMOTE_APP_BAR_WIDTH_PX,
             y: EMOTE_APP_BAR_HEIGHT_PX
         },
-        position: {
-            x: Window.x + EMOTE_APP_BAR_LEFT_MARGIN,
-            y: Window.y + Window.innerHeight - EMOTE_APP_BAR_BOTTOM_MARGIN
+        relativePosition: {
+            x: EMOTE_APP_BAR_LEFT_MARGIN,
+            y: EMOTE_APP_BAR_BOTTOM_MARGIN
         },
+        relativePositionAnchor: Desktop.RelativePositionAnchor.BOTTOM_LEFT,
         overrideFlags: EMOTE_APP_BAR_WINDOW_FLAGS
     });
 
@@ -550,10 +543,18 @@ function showEmoteAppBar() {
 }
 
 
-function handleEmoteIndicatorVisibleChanged(shouldBeVisible) {
-    if (shouldBeVisible && !emoteAppBarWindow) {
+// There is currently no property in the Window Scripting Interface to determine
+// whether the Interface window is currently minimized. This feels like an oversight.
+// We should add that functionality to the Window Scripting Interface, and remove `isWindowMinimized` below.
+var isWindowMinimized = false;
+function maybeChangeEmoteIndicatorVisibility(desiredVisibility) {
+    if (isWindowMinimized || HMD.active) {
+        desiredVisibility = false;
+    }
+
+    if (desiredVisibility && !emoteAppBarWindow) {
         showEmoteAppBar();
-    } else if (emoteAppBarWindow) {
+    } else if (!desiredVisibility && emoteAppBarWindow) {
         emoteAppBarWindow.fromQml.disconnect(onMessageFromEmoteAppBar);
         emoteAppBarWindow.close();
         emoteAppBarWindow = false;
@@ -561,23 +562,25 @@ function handleEmoteIndicatorVisibleChanged(shouldBeVisible) {
 }
 
 
+function handleFTUEScreensVisibilityChanged(ftueScreenVisible) {
+    maybeChangeEmoteIndicatorVisibility(!ftueScreenVisible);
+}
+
+
 function onDisplayModeChanged(isHMDMode) {
     reactionsBegun.forEach(function(react) {
         endReactionWrapper(react);
     });
 
-    if (isHMDMode) {
-        handleEmoteIndicatorVisibleChanged(false);
-    } else {
-        handleEmoteIndicatorVisibleChanged(true);
-    }
+    maybeChangeEmoteIndicatorVisibility(!isHMDMode);
 }
 
 
-var emojiAPI = Script.require("./emojiApp/simplifiedEmoji.js?" + Date.now());
+var emojiAPI = Script.require("./emojiApp/simplifiedEmoji.js");
 var keyPressSignalsConnected = false;
 var emojiCodeMap;
 var customEmojiCodeMap;
+var _this;
 function setup() {
     deleteOldReticles();
 
@@ -605,16 +608,25 @@ function setup() {
     }, {});
 
     Window.minimizedChanged.connect(onWindowMinimizedChanged);
-    Window.geometryChanged.connect(onGeometryChanged);
     HMD.displayModeChanged.connect(onDisplayModeChanged);
 
     getSounds();
-    handleEmoteIndicatorVisibleChanged(true);
+    maybeChangeEmoteIndicatorVisibility(true);
     
     Controller.keyPressEvent.connect(keyPressHandler);
     Controller.keyReleaseEvent.connect(keyReleaseHandler);
     keyPressSignalsConnected = true;
     Script.scriptEnding.connect(unload);
+    
+    function Emote() {
+        _this = this;
+    }
+
+    Emote.prototype = {
+        handleFTUEScreensVisibilityChanged: handleFTUEScreensVisibilityChanged
+    };
+
+    return new Emote();
 }
 
 
@@ -638,7 +650,6 @@ function unload() {
     maybeDeleteRemoteIndicatorTimeout();
 
     Window.minimizedChanged.disconnect(onWindowMinimizedChanged);
-    Window.geometryChanged.disconnect(onGeometryChanged);
     HMD.displayModeChanged.disconnect(onDisplayModeChanged);
 
     if (keyPressSignalsConnected) {
@@ -671,7 +682,6 @@ function unload() {
 // #region EMOJI_UTILITY
 
 
-var EMOJI_52_BASE_URL = "../../resources/images/emojis/52px/";
 function selectedEmoji(code) {
     emojiAPI.addEmoji(code);
     // this URL needs to be relative to SimplifiedEmoteIndicator.qml
@@ -786,4 +796,6 @@ function toggleEmojiApp() {
 // END EMOJI
 // *************************************
 
-setup();
\ No newline at end of file
+var emote = setup();
+
+module.exports = emote;
\ No newline at end of file
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/InitialLaunchWindow.qml b/scripts/simplifiedUI/ui/simplifiedFTUE/InitialLaunchWindow.qml
new file mode 100644
index 0000000000..1938586edb
--- /dev/null
+++ b/scripts/simplifiedUI/ui/simplifiedFTUE/InitialLaunchWindow.qml
@@ -0,0 +1,350 @@
+//
+//  InitialLaunchWindow.qml
+//
+//  Copyright 2019 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtGraphicalEffects 1.0
+import QtQuick.Layouts 1.3
+import stylesUit 1.0 as HifiStylesUit
+import TabletScriptingInterface 1.0
+import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
+import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
+
+Rectangle {
+    id: root
+    color: simplifiedUI.colors.white
+    anchors.fill: parent
+    property bool landscapeOrientation: root.width > root.height
+
+    SimplifiedConstants.SimplifiedConstants {
+        id: simplifiedUI
+    }
+
+    Component.onCompleted: {
+        var debugFTUE = Settings.getValue("simplifiedUI/debugFTUE", 0);
+
+        if ((debugFTUE !== 1 &&
+            (Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", false) || 
+            Settings.getValue("simplifiedUI/closedAvatarPageOfInitialLaunchWindow", false))) ||
+            debugFTUE === 2) {
+            tempAvatarPageContainer.visible = false;
+            controlsContainer.visible = true;
+        }
+    }
+
+    Item {
+        id: tempAvatarPageContainer
+        anchors.fill: parent
+
+        Item {
+            id: contentContainer
+            anchors.top: parent.top
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.bottom: firstPageBottomBarContainer.top
+
+            Image {
+                id: avatarImage
+                anchors.verticalCenter: parent.verticalCenter
+                height: Math.max(parent.height - 48, 350)
+                anchors.left: parent.left
+                anchors.leftMargin: 12
+                source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/" +
+                    MyAvatar.skeletonModelURL.substring(MyAvatar.skeletonModelURL.indexOf("simplifiedAvatar"), MyAvatar.skeletonModelURL.lastIndexOf("/")) + ".png"
+                mipmap: true
+                fillMode: Image.PreserveAspectFit
+            }
+
+            Flickable {
+                id: textContainer
+                clip: true
+                anchors.top: parent.top
+                anchors.topMargin: 128
+                anchors.bottom: qrAndInstructionsContainer.top
+                anchors.bottomMargin: 32
+                anchors.left: avatarImage.right
+                anchors.leftMargin: 48
+                anchors.right: parent.right
+                contentWidth: width
+                contentHeight: contentItem.childrenRect.height
+                interactive: contentHeight > height
+
+                HifiStylesUit.RalewayBold {
+                    id: headerText
+                    text: "We know this isn't you..."
+                    color: simplifiedUI.colors.text.black
+                    size: 48
+                    height: paintedHeight
+                    wrapMode: Text.Wrap
+                    anchors.top: parent.top
+                    anchors.left: parent.left
+                    anchors.right: parent.right
+                    anchors.rightMargin: 16
+                }
+
+                HifiStylesUit.RalewayRegular {
+                    id: descriptionText
+                    anchors.top: headerText.bottom
+                    anchors.topMargin: 10
+                    anchors.left: parent.left
+                    width: Math.min(700, parent.width) - headerText.anchors.rightMargin
+                    height: paintedHeight
+                    text: "...but we've given you this <b>temporary avatar</b> to use " +
+                        "for today. If you see this avatar in-world, walk up and " +
+                        "say hello to other new users!<br><br>" +
+                        "<b>We want you to be you</b> so we've built " +
+                        '<a href="https://www.highfidelity.com/knowledge/virtual-you/">Virtual You</a>, an Avatar Creator ' +
+                        "App. Creating an avatar is as easy as taking a selfie and picking your " +
+                        "outfits! Available now on iOS and Android."
+                    color: simplifiedUI.colors.text.black
+                    size: 22
+                    wrapMode: Text.Wrap
+
+                    onLinkActivated: {
+                        Qt.openUrlExternally(link);
+                    }
+                }
+            }
+
+            Item {
+                id: qrAndInstructionsContainer
+                anchors.left: avatarImage.right
+                anchors.leftMargin: 48
+                anchors.right: parent.right
+                anchors.rightMargin: 16
+                anchors.bottom: parent.bottom
+                height: 130
+
+                Image {
+                    id: avatarAppQRCodeImage
+                    source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg"
+                    anchors.top: parent.top
+                    anchors.bottom: parent.bottom
+                    anchors.left: parent.left
+                    width: 130
+                    mipmap: true
+                    fillMode: Image.PreserveAspectFit
+                }
+
+                HifiStylesUit.RalewayBold {
+                    id: instructionText
+                    anchors.top: avatarAppQRCodeImage.top
+                    anchors.bottom: avatarAppQRCodeImage.bottom
+                    anchors.left: avatarAppQRCodeImage.right
+                    anchors.leftMargin: 30
+                    anchors.right: parent.right
+                    text: "Use your mobile phone to scan this QR code."
+                    color: simplifiedUI.colors.text.black
+                    size: 22
+                    wrapMode: Text.Wrap
+                }
+            }
+
+            SimplifiedControls.VerticalScrollBar {
+                parent: textContainer
+                visible: parent.contentHeight > parent.height
+                size: parent.height / parent.contentHeight
+            }
+        }        
+
+        Item {
+            id: firstPageBottomBarContainer
+            anchors.left: parent.left
+            anchors.leftMargin: 32
+            anchors.right: parent.right
+            anchors.rightMargin: 32
+            anchors.bottom: parent.bottom
+            height: continueLink.height + 48
+        
+            HifiStylesUit.RalewayBold {
+                id: continueLink
+                anchors.centerIn: parent
+                text: "Continue >"
+                width: parent.width
+                height: paintedHeight
+                color: simplifiedUI.colors.text.lightBlue
+                opacity: continueMouseArea.containsMouse ? 1.0 : 0.7
+                size: 36
+                wrapMode: Text.Wrap
+                horizontalAlignment: Text.AlignHCenter
+
+                MouseArea {
+                    id: continueMouseArea
+                    hoverEnabled: true
+                    anchors.fill: parent
+
+                    onClicked: {
+                        Tablet.playSound(TabletEnums.ButtonClick);
+                        tempAvatarPageContainer.visible = false;
+                        Settings.setValue("simplifiedUI/closedAvatarPageOfInitialLaunchWindow", true);
+                        controlsContainer.visible = true;
+                    }
+                }
+            }
+        }
+    }
+
+    Item {
+        id: controlsContainer
+        visible: false
+        anchors.fill: parent
+
+        HifiStylesUit.RalewayRegular {
+            id: controlsDescriptionText
+            text: "Use these avatar controls to<br><b>interact with and move around in your new HQ.</b>"
+            anchors.top: parent.top
+            anchors.topMargin: 48
+            anchors.left: parent.left
+            anchors.leftMargin: 32
+            anchors.right: parent.right
+            anchors.rightMargin: 32
+            horizontalAlignment: Text.AlignHCenter
+            height: paintedHeight
+            color: simplifiedUI.colors.text.black
+            size: 36
+            wrapMode: Text.Wrap
+        }
+
+        Item {
+            anchors.top: controlsDescriptionText.bottom
+            anchors.topMargin: 16
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.bottom: bottomBarContainer.top
+
+            GridView {
+                id: controlsGrid
+                property int maxColumns: 2
+                property int idealCellWidth: 361
+                anchors.fill: parent
+                clip: true
+                cellWidth: width / Math.min(Math.floor(width / idealCellWidth), maxColumns)
+                cellHeight: 225
+                model: ListModel {
+                    ListElement {
+                        imageHeight: 198
+                        imageSource: "images/walkingControls.png"
+                    }
+                    ListElement {
+                        imageHeight: 193
+                        imageSource: "images/mouseControls.png"
+                    }
+                    ListElement {
+                        imageHeight: 146
+                        imageSource: "images/runJumpControls.png"
+                    }
+                    ListElement {
+                        imageHeight: 96
+                        imageSource: "images/cameraControls.png"
+                    }
+                }
+                delegate: Rectangle {
+                    height: GridView.view.cellHeight
+                    width: GridView.view.cellWidth
+                    Image {
+                        anchors.centerIn: parent
+                        width: parent.GridView.view.idealCellWidth
+                        height: model.imageHeight
+                        source: model.imageSource
+                        fillMode: Image.PreserveAspectFit
+                    }
+                }
+            }
+
+            SimplifiedControls.VerticalScrollBar {
+                parent: controlsGrid
+                anchors.topMargin: 96
+                anchors.bottomMargin: anchors.topMargin
+            }
+        }
+
+        Item {
+            id: bottomBarContainer
+            anchors.left: parent.left
+            anchors.leftMargin: 32
+            anchors.right: parent.right
+            anchors.rightMargin: 32
+            anchors.bottom: parent.bottom
+            height: iHaveAGoodGrip.height + learnMoreLink.height + 48
+
+            HifiStylesUit.RalewayBold {
+                id: iHaveAGoodGrip
+                anchors.centerIn: parent
+                text: "I've got a good grip on the controls."
+                width: parent.width
+                height: paintedHeight
+                color: simplifiedUI.colors.text.lightBlue
+                opacity: goodGripMouseArea.containsMouse ? 1.0 : 0.7
+                size: 36
+                wrapMode: Text.Wrap
+                horizontalAlignment: Text.AlignHCenter
+
+                MouseArea {
+                    id: goodGripMouseArea
+                    hoverEnabled: true
+                    anchors.fill: parent
+
+                    onClicked: {
+                        Tablet.playSound(TabletEnums.ButtonClick);
+                        sendToScript({
+                            "source": "InitialLaunchWindow.qml",
+                            "method": "closeInitialLaunchWindow"
+                        });
+                    }
+                }
+            }
+        
+            HifiStylesUit.RalewayBold {
+                id: learnMoreLink
+                anchors.left: parent.left
+                anchors.leftMargin: 16
+                anchors.top: iHaveAGoodGrip.bottom
+                anchors.topMargin: 8
+                text: "Learn more about our controls."
+                width: paintedWidth
+                height: paintedHeight
+                color: simplifiedUI.colors.text.lightBlue
+                opacity: learnMoreAboutControlsMouseArea.containsMouse ? 1.0 : 0.7
+                size: 14
+                wrapMode: Text.Wrap
+
+                MouseArea {
+                    id: learnMoreAboutControlsMouseArea
+                    hoverEnabled: true
+                    anchors.fill: parent
+
+                    onClicked: {
+                        Tablet.playSound(TabletEnums.ButtonClick);
+                        Qt.openUrlExternally("https://www.highfidelity.com/knowledge/get-around");
+                    }
+                }
+            }
+        }
+    }
+
+    Image {
+        id: topLeftAccentImage
+        width: 400
+        height: 180
+        anchors.left: parent.left
+        anchors.top: parent.top
+        source: "images/defaultTopLeft.png"
+    }
+
+    Image {
+        id: bottomRightAccentImage
+        width: 80
+        height: 250
+        anchors.right: parent.right
+        anchors.bottom: parent.bottom
+        source: "images/defaultBottomRight.png"
+    }
+
+    signal sendToScript(var message);
+}
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/SecondLaunchWindow.qml b/scripts/simplifiedUI/ui/simplifiedFTUE/SecondLaunchWindow.qml
new file mode 100644
index 0000000000..2a796465ae
--- /dev/null
+++ b/scripts/simplifiedUI/ui/simplifiedFTUE/SecondLaunchWindow.qml
@@ -0,0 +1,186 @@
+//
+//  SecondLaunchWindow.qml
+//
+//  Copyright 2019 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtGraphicalEffects 1.0
+import QtQuick.Layouts 1.3
+import stylesUit 1.0 as HifiStylesUit
+import TabletScriptingInterface 1.0
+import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
+import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
+
+Rectangle {
+    id: root
+    color: simplifiedUI.colors.white
+    anchors.fill: parent
+
+    SimplifiedConstants.SimplifiedConstants {
+        id: simplifiedUI
+    }
+
+    Item {
+        id: contentContainer
+        anchors.top: parent.top
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.bottom: continueLink.top
+
+        Image {
+            id: avatarImage
+            anchors.verticalCenter: parent.verticalCenter
+            height: Math.max(parent.height - 48, 350)
+            anchors.left: parent.left
+            anchors.leftMargin: 12
+            source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/hero.png"
+            mipmap: true
+            fillMode: Image.PreserveAspectFit
+        }
+
+        Item {
+            anchors.top: parent.top
+            anchors.topMargin: 196
+            anchors.bottom: parent.bottom
+            anchors.bottomMargin: 32
+            anchors.left: avatarImage.right
+            anchors.leftMargin: 48
+            anchors.right: parent.right
+
+            Flickable {
+                id: textContainer
+                clip: true
+                anchors.top: parent.top
+                anchors.bottom: parent.bottom
+                anchors.left: parent.left
+                width: Math.min(700, parent.width)
+                contentWidth: width
+                contentHeight: contentItem.childrenRect.height
+                interactive: contentHeight > height
+
+                HifiStylesUit.RalewayBold {
+                    id: headerText
+                    text: "Stand out from the crowd!"
+                    color: simplifiedUI.colors.text.black
+                    size: 48
+                    height: paintedHeight
+                    wrapMode: Text.Wrap
+                    anchors.top: parent.top
+                    anchors.left: parent.left
+                    anchors.right: parent.right
+                    anchors.rightMargin: 16
+                }
+
+                HifiStylesUit.RalewayRegular {
+                    id: descriptionText
+                    anchors.top: headerText.bottom
+                    anchors.topMargin: 10
+                    anchors.left: parent.left
+                    width: parent.width - headerText.anchors.rightMargin
+                    height: paintedHeight
+                    text: "You can create and upload custom avatars from our Avatar Creator App. " +
+                        "It's as easy as taking a selfie.<br>Available now on iOS and Android Platforms."
+                    color: simplifiedUI.colors.text.black
+                    size: 22
+                    wrapMode: Text.Wrap
+                }
+
+                Item {
+                    id: qrAndInstructionsContainer
+                    anchors.top: descriptionText.bottom
+                    anchors.topMargin: 24
+                    anchors.left: parent.left
+                    anchors.right: parent.right
+                    anchors.rightMargin: 16
+                    height: avatarAppQRCodeImage.height
+
+                    Image {
+                        id: avatarAppQRCodeImage
+                        source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg"
+                        anchors.top: parent.top
+                        anchors.left: parent.left
+                        width: 130
+                        height: width
+                        mipmap: true
+                        fillMode: Image.PreserveAspectFit
+                    }
+
+                    HifiStylesUit.RalewayBold {
+                        id: instructionText
+                        anchors.top: avatarAppQRCodeImage.top
+                        anchors.bottom: avatarAppQRCodeImage.bottom
+                        anchors.left: avatarAppQRCodeImage.right
+                        anchors.leftMargin: 30
+                        anchors.right: parent.right
+                        text: "Use your mobile phone to scan this QR code."
+                        color: simplifiedUI.colors.text.black
+                        size: 22
+                        wrapMode: Text.Wrap
+                    }
+                }
+            }
+        }
+
+        SimplifiedControls.VerticalScrollBar {
+            parent: textContainer
+            visible: parent.contentHeight > parent.height
+            size: parent.height / parent.contentHeight
+        }
+    }
+        
+
+    HifiStylesUit.RalewayBold {
+        id: continueLink
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.leftMargin: 16
+        anchors.right: parent.right
+        anchors.rightMargin: 16
+        height: 96
+        horizontalAlignment: Text.AlignHCenter
+        verticalAlignment: Text.AlignVCenter
+        text: "No thanks, I'll keep using my default avatar."
+        color: simplifiedUI.colors.text.lightBlue
+        opacity: continueMouseArea.containsMouse ? 1.0 : 0.7
+        size: 24
+
+        MouseArea {
+            id: continueMouseArea
+            hoverEnabled: true
+            anchors.fill: parent
+
+            onClicked: {
+                Tablet.playSound(TabletEnums.ButtonClick);
+                sendToScript({
+                    "source": "SecondLaunchWindow.qml",
+                    "method": "closeSecondLaunchWindow"
+                });
+            }
+        }
+    }
+
+    Image {
+        id: topLeftAccentImage
+        width: 130
+        height: 320
+        anchors.left: parent.left
+        anchors.top: parent.top
+        source: "images/standOutTopLeft.png"
+    }
+
+    Image {
+        id: bottomRightAccentImage
+        width: 250
+        height: 80
+        anchors.right: parent.right
+        anchors.bottom: parent.bottom
+        source: "images/standOutBottomRight.png"
+    }
+
+    signal sendToScript(var message);
+}
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/cameraControls.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/cameraControls.png
new file mode 100644
index 0000000000..e54e26a3ba
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/cameraControls.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultBottomRight.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultBottomRight.png
new file mode 100644
index 0000000000..1668347aa4
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultBottomRight.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultTopLeft.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultTopLeft.png
new file mode 100644
index 0000000000..c863569d7f
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultTopLeft.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/mouseControls.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/mouseControls.png
new file mode 100644
index 0000000000..6354b1aeae
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/mouseControls.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/runJumpControls.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/runJumpControls.png
new file mode 100644
index 0000000000..af0492475d
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/runJumpControls.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutBottomRight.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutBottomRight.png
new file mode 100644
index 0000000000..8b9983bb88
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutBottomRight.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutTopLeft.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutTopLeft.png
new file mode 100644
index 0000000000..30cb623f42
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/standOutTopLeft.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedFTUE/images/walkingControls.png b/scripts/simplifiedUI/ui/simplifiedFTUE/images/walkingControls.png
new file mode 100644
index 0000000000..bedc6991bb
Binary files /dev/null and b/scripts/simplifiedUI/ui/simplifiedFTUE/images/walkingControls.png differ
diff --git a/scripts/simplifiedUI/ui/simplifiedUI.js b/scripts/simplifiedUI/ui/simplifiedUI.js
index f0a76f4f5f..fc0dd9fddd 100644
--- a/scripts/simplifiedUI/ui/simplifiedUI.js
+++ b/scripts/simplifiedUI/ui/simplifiedUI.js
@@ -14,7 +14,6 @@
 
 
 // START CONFIG OPTIONS
-var DOCKED_QML_SUPPORTED = true;
 var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system";
 var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/";
 // END CONFIG OPTIONS
@@ -352,6 +351,124 @@ function setOutputMuted(outputMuted) {
     }
 }
 
+var TOP_BAR_HEIGHT_PX = 48;
+var INITIAL_LAUNCH_QML_PATH = Script.resolvePath("./simplifiedFTUE/InitialLaunchWindow.qml");
+var INITIAL_LAUNCH_WINDOW_TITLE = "Initial Launch";
+var INITIAL_LAUNCH_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
+var INITIAL_WINDOW_FLAGS = 0x00000001 | // Qt::Window
+0x00000008 | // Qt::Popup
+0x00000002 | // Qt::Tool
+0x00000800 | // Qt::FramelessWindowHint
+0x40000000; // Qt::NoDropShadowWindowHint
+var initialLaunchWindow = false;
+function displayInitialLaunchWindow() {
+    if (initialLaunchWindow) {
+        return;
+    }
+
+    simplifiedEmote.handleFTUEScreensVisibilityChanged(true);
+
+    initialLaunchWindow = Desktop.createWindow(INITIAL_LAUNCH_QML_PATH, {
+        title: INITIAL_LAUNCH_WINDOW_TITLE,
+        presentationMode: INITIAL_LAUNCH_PRESENTATION_MODE,
+        isFullScreenWindow: true,
+        overrideFlags: INITIAL_WINDOW_FLAGS
+    });
+
+    initialLaunchWindow.fromQml.connect(onMessageFromInitialLaunchWindow);
+
+    Window.location = "file:///~/serverless/tutorial.json";
+}
+
+var SECOND_LAUNCH_QML_PATH = Script.resolvePath("simplifiedFTUE/SecondLaunchWindow.qml");
+var SECOND_LAUNCH_WINDOW_TITLE = "Second Launch";
+var SECOND_LAUNCH_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
+var SECOND_WINDOW_FLAGS = 0x00000001 | // Qt::Window
+0x00000008 | // Qt::Popup
+0x00000002 | // Qt::Tool
+0x00000800 | // Qt::FramelessWindowHint
+0x40000000; // Qt::NoDropShadowWindowHint
+var secondLaunchWindow = false;
+function displaySecondLaunchWindow() {
+    if (secondLaunchWindow) {
+        return;
+    }
+
+    simplifiedEmote.handleFTUEScreensVisibilityChanged(true);
+
+    secondLaunchWindow = Desktop.createWindow(SECOND_LAUNCH_QML_PATH, {
+        title: SECOND_LAUNCH_WINDOW_TITLE,
+        presentationMode: SECOND_LAUNCH_PRESENTATION_MODE,
+        isFullScreenWindow: true,
+        overrideFlags: SECOND_WINDOW_FLAGS
+    });
+
+    secondLaunchWindow.fromQml.connect(onMessageFromSecondLaunchWindow);
+
+    Window.location = "file:///~/serverless/tutorial.json";
+}
+
+function closeInitialLaunchWindow() {
+    if (initialLaunchWindow) {
+        initialLaunchWindow.fromQml.disconnect(onMessageFromInitialLaunchWindow);
+        initialLaunchWindow.close();
+        initialLaunchWindow = null;
+    }
+
+    simplifiedEmote.handleFTUEScreensVisibilityChanged(false);
+}
+
+function closeSecondLaunchWindow() {
+    if (secondLaunchWindow) {
+        secondLaunchWindow.fromQml.disconnect(onMessageFromSecondLaunchWindow);
+        secondLaunchWindow.close();
+        secondLaunchWindow = null;
+    }
+
+    simplifiedEmote.handleFTUEScreensVisibilityChanged(false);
+}
+
+var INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE = "InitialLaunchWindow.qml";
+function onMessageFromInitialLaunchWindow(message) {
+    if (message.source !== INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE) {
+        return;
+    }
+
+    switch (message.method) {
+        case "closeInitialLaunchWindow":
+            closeInitialLaunchWindow();
+            var homeLocation = LocationBookmarks.getAddress("hqhome");
+            if (homeLocation) {
+                Window.location = homeLocation;
+            }
+            break;
+
+        default:
+            console.log("Unrecognized message from " + INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE + ": " + JSON.stringify(message));
+            break;
+    }
+}
+
+var SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE = "SecondLaunchWindow.qml";
+function onMessageFromSecondLaunchWindow(message) {
+    if (message.source !== SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE) {
+        return;
+    }
+
+    switch (message.method) {
+        case "closeSecondLaunchWindow":
+            closeSecondLaunchWindow();
+            var homeLocation = LocationBookmarks.getAddress("hqhome");
+            if (homeLocation) {
+                Window.location = homeLocation;
+            }
+            break;
+
+        default:
+            console.log("Unrecognized message from " + SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE + ": " + JSON.stringify(message));
+            break;
+    }
+}
 
 var WAIT_FOR_TOP_BAR_MS = 1000;
 function sendLocalStatusToQml() {
@@ -397,6 +514,14 @@ function onMessageFromTopBar(message) {
             si.toggleStatus();
             break;
 
+        case "displayInitialLaunchWindow":
+            displayInitialLaunchWindow();
+            break;
+
+        case "displaySecondLaunchWindow":
+            displaySecondLaunchWindow();
+            break;
+
         default:
             console.log("Unrecognized message from " + TOP_BAR_MESSAGE_SOURCE + ": " + JSON.stringify(message));
             break;
@@ -425,7 +550,6 @@ var TOP_BAR_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/topBar/Si
 var TOP_BAR_WINDOW_TITLE = "Simplified Top Bar";
 var TOP_BAR_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
 var TOP_BAR_WIDTH_PX = Window.innerWidth;
-var TOP_BAR_HEIGHT_PX = 48;
 var topBarWindow = false;
 function loadSimplifiedTopBar() {
     var windowProps = {
@@ -436,16 +560,9 @@ function loadSimplifiedTopBar() {
             y: TOP_BAR_HEIGHT_PX
         }
     };
-    if (DOCKED_QML_SUPPORTED) {
-        windowProps.presentationWindowInfo = {
-            dockArea: Desktop.DockArea.TOP
-        };
-    } else {
-        windowProps.position = {
-            x: Window.x,
-            y: Window.y
-        };
-    }
+    windowProps.presentationWindowInfo = {
+        dockArea: Desktop.DockArea.TOP
+    };
     topBarWindow = Desktop.createWindow(TOP_BAR_QML_PATH, windowProps);
 
     topBarWindow.fromQml.connect(onMessageFromTopBar);
@@ -510,21 +627,38 @@ function onHMDInputDeviceMutedChanged(isMuted) {
 function onGeometryChanged(rect) {
     updateInputDeviceMutedOverlay(Audio.muted);
     updateOutputDeviceMutedOverlay(isOutputMuted());
-    if (topBarWindow && !DOCKED_QML_SUPPORTED) {
-        topBarWindow.size = {
-            "x": rect.width,
-            "y": TOP_BAR_HEIGHT_PX
-        };
-        topBarWindow.position = {
-            "x": rect.x,
-            "y": rect.y
-        };
+}
+
+var initialLaunchWindowIsMinimized = false;
+var secondLaunchWindowIsMinimized = false;
+function onWindowMinimizedChanged(isMinimized) {
+    if (isMinimized) {
+        handleInitialLaunchWindowVisibleChanged(false);
+        handleSecondLaunchWindowVisibleChanged(false);
+    } else if (!HMD.active) {
+        handleInitialLaunchWindowVisibleChanged(true);
+        handleSecondLaunchWindowVisibleChanged(true);
     }
 }
 
-function onWindowMinimizedChanged() {
-    // prerequisite placeholder for Reduce Friction of Customer Acquisition sub task: https://highfidelity.atlassian.net/browse/DEV-585
-    print("WINDOW MINIMIZED CHANGED SIGNAL");
+function handleInitialLaunchWindowVisibleChanged(shouldBeVisible) {
+    if (shouldBeVisible && !initialLaunchWindow && initialLaunchWindowIsMinimized) {
+        displayInitialLaunchWindow();
+        initialLaunchWindowIsMinimized = false;
+    } else if (!shouldBeVisible && initialLaunchWindow) {
+        closeInitialLaunchWindow();
+        initialLaunchWindowIsMinimized = true;
+    }
+}
+
+function handleSecondLaunchWindowVisibleChanged(shouldBeVisible) {
+    if (shouldBeVisible && !secondLaunchWindow && secondLaunchWindowIsMinimized) {
+        displaySecondLaunchWindow();
+        secondLaunchWindowIsMinimized = false;
+    } else if (!shouldBeVisible && secondLaunchWindow) {
+        closeSecondLaunchWindow();
+        secondLaunchWindowIsMinimized = true;
+    }
 }
 
 function onDisplayModeChanged(isHMDMode) {
@@ -534,8 +668,12 @@ function onDisplayModeChanged(isHMDMode) {
 
     if (isHMDMode) {
         onHMDInputDeviceMutedChanged(Audio.mutedHMD);
+        handleInitialLaunchWindowVisibleChanged(false);
+        handleSecondLaunchWindowVisibleChanged(false);
     } else {
         onDesktopInputDeviceMutedChanged(Audio.mutedDesktop);
+        handleInitialLaunchWindowVisibleChanged(true);
+        handleSecondLaunchWindowVisibleChanged(true);
     }
 }
 
@@ -578,9 +716,9 @@ function restoreLODSettings() {
 }
 
 
-var nametag = Script.require("./simplifiedNametag/simplifiedNametag.js?" + Date.now());
-var si = Script.require("./simplifiedStatusIndicator/simplifiedStatusIndicator.js?" + Date.now());
-var emote = Script.require("../simplifiedEmote/simplifiedEmote.js?" + Date.now());
+var nametag = Script.require("./simplifiedNametag/simplifiedNametag.js");
+var si = Script.require("./simplifiedStatusIndicator/simplifiedStatusIndicator.js");
+var simplifiedEmote = Script.require("../simplifiedEmote/simplifiedEmote.js");
 var oldShowAudioTools;
 var oldShowBubbleTools;
 var keepExistingUIAndScriptsSetting = Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false);
@@ -647,6 +785,14 @@ function shutdown() {
         settingsAppWindow.close();
     }
 
+    if (initialLaunchWindow) {
+        closeInitialLaunchWindow();
+    }
+
+    if (secondLaunchWindow) {
+        closeSecondLaunchWindow();
+    }
+
     maybeDeleteInputDeviceMutedOverlay();
     maybeDeleteOutputDeviceMutedOverlay();