diff --git a/package.json b/package.json
index 24b2fabe5366c9ec13e322f6a9fe9ee296f62bf1..a3ff0b80b12f0ff763551c8bd08a572f0b2f286a 100644
--- a/package.json
+++ b/package.json
@@ -95,17 +95,13 @@
     "redux-throttle": "0.1.1",
     "rimraf": "^2.6.1",
     "scratch-audio": "0.1.0-prerelease.20180625202813",
-    "scratch-blocks": "0.1.0-prerelease.1530135682",
-    "scratch-l10n": "3.0.20180611175036",
-    "scratch-paint": "0.2.0-prerelease.20180629115559",
-    "scratch-audio": "0.1.0-prerelease.20180625202813",
-    "scratch-blocks": "0.1.0-prerelease.1530135682",
-    "scratch-l10n": "3.0.20180627134459",
-    "scratch-paint": "0.2.0-prerelease.20180629115559",
+    "scratch-blocks": "0.1.0-prerelease.1531144787",
+    "scratch-l10n": "3.0.20180703181510",
+    "scratch-paint": "0.2.0-prerelease.20180709132225",
     "scratch-render": "0.1.0-prerelease.20180618173030",
     "scratch-storage": "0.5.1",
     "scratch-svg-renderer": "0.2.0-prerelease.20180618172917",
-    "scratch-vm": "0.1.0-prerelease.1529940524",
+    "scratch-vm": "0.1.0-prerelease.1530902855",
     "selenium-webdriver": "3.6.0",
     "startaudiocontext": "1.2.1",
     "style-loader": "^0.21.0",
diff --git a/src/components/forms/label.css b/src/components/forms/label.css
index 8ec6283bf7b61e91ad231780e7a4e9b596b17379..759a731d37efca6effb443534f24ed17e30bec5c 100644
--- a/src/components/forms/label.css
+++ b/src/components/forms/label.css
@@ -12,6 +12,8 @@
     margin-right: .5rem;
     user-select: none;
     cursor: default;
+
+    white-space: nowrap;
 }
 
 .input-label {
diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css
index af7500fb0a3d9e0fd57c3bda81a3fa3fe5d97a95..b53f17b55ebd42e6cc7cad2dae2d6903dbcb44cb 100644
--- a/src/components/gui/gui.css
+++ b/src/components/gui/gui.css
@@ -79,6 +79,7 @@
     align-items: center;
 
     user-select: none;
+    white-space: nowrap;
 }
 
 /* Use z-indices to force left-on-top for tabs */
diff --git a/src/components/prompt/prompt.css b/src/components/prompt/prompt.css
index 34a8f5a21e3aea6ef4817aa6a2158232ca59d18d..78e3ecb27c6b3d2583528ed1dc6b1df6f36dca6e 100644
--- a/src/components/prompt/prompt.css
+++ b/src/components/prompt/prompt.css
@@ -15,7 +15,7 @@
     margin: 0 0 0.75rem;
 }
 
-.input {
+.variable-name-text-input {
     margin-bottom: 1.5rem;
     width: 100%;
     border: 1px solid $ui-black-transparent;
@@ -26,6 +26,20 @@
     font-size: .875rem;
 }
 
+.info-message {
+    font-weight: normal;
+    font-size: .875rem;
+    margin-bottom: 1.5rem;
+    text-align: center;
+}
+
+.options-row {
+    display: flex;
+    font-weight: normal;
+    justify-content: space-between;
+    margin-bottom: 1.5rem;
+}
+
 .button-row {
     font-weight: bolder;
     text-align: right;
@@ -58,10 +72,6 @@
     margin: 0 0 1rem;
 }
 
-.hide-more-options {
-    display: none;
-}
-
 .more-options-accordion {
     width: 60%;
     margin: 0 auto;
diff --git a/src/components/prompt/prompt.jsx b/src/components/prompt/prompt.jsx
index 4feffeb0c8205784938ba1e586c0027bc9de6a05..3e5ec7950fc1be25a4e5cc89297a9828237fd649 100644
--- a/src/components/prompt/prompt.jsx
+++ b/src/components/prompt/prompt.jsx
@@ -11,10 +11,26 @@ import styles from './prompt.css';
 import dropdownIcon from './icon--dropdown-caret.svg';
 
 const messages = defineMessages({
+    forAllSpritesMessage: {
+        defaultMessage: 'For all sprites',
+        description: 'Option message when creating a variable for making it available to all sprites',
+        id: 'gui.gui.variableScopeOptionAllSprites'
+    },
+    forThisSpriteMessage: {
+        defaultMessage: 'For this sprite only',
+        description: 'Option message when creating a varaible for making it only available to the current sprite',
+        id: 'gui.gui.variableScopeOptionSpriteOnly'
+    },
     moreOptionsMessage: {
         defaultMessage: 'More Options',
         description: 'Dropdown message for variable/list options',
         id: 'gui.gui.variablePrompt'
+    },
+    availableToAllSpritesMessage: {
+        defaultMessage: 'This variable will be available to all sprites.',
+        description: 'A message that displays in a variable modal when the stage is selected indicating ' +
+            'that the variable being created will available to all sprites.',
+        id: 'gui.gui.variablePromptAllSpritesMessage'
     }
 });
 
@@ -31,29 +47,64 @@ const PromptComponent = props => (
             <Box>
                 <input
                     autoFocus
-                    className={styles.input}
+                    className={styles.variableNameTextInput}
                     placeholder={props.placeholder}
                     onChange={props.onChange}
                     onKeyPress={props.onKeyPress}
                 />
             </Box>
-            <Box className={props.showMoreOptions ? styles.moreOptions : styles.hideMoreOptions}>
-                <ComingSoonTooltip
-                    className={styles.moreOptionsAccordion}
-                    place="right"
-                    tooltipId="variable-options-accordion"
-                >
-                    <div className={styles.moreOptionsText}>
-                        <FormattedMessage
-                            {...messages.moreOptionsMessage}
-                        />
-                        <img
-                            className={styles.moreOptionsIcon}
-                            src={dropdownIcon}
-                        />
-                    </div>
-                </ComingSoonTooltip>
-            </Box>
+            {props.showMoreOptions ?
+                <div>
+                    {props.isStage ?
+                        <div className={styles.infoMessage}>
+                            <FormattedMessage
+                                {...messages.availableToAllSpritesMessage}
+                            />
+                        </div> :
+                        <Box className={styles.optionsRow}>
+                            <label>
+                                <input
+                                    defaultChecked
+                                    name="variableScopeOption"
+                                    type="radio"
+                                    value="global"
+                                    onChange={props.onOptionSelection}
+                                />
+                                <FormattedMessage
+                                    {...messages.forAllSpritesMessage}
+                                />
+                            </label>
+                            <label>
+                                <input
+                                    name="variableScopeOption"
+                                    type="radio"
+                                    value="local"
+                                    onChange={props.onOptionSelection}
+                                />
+                                <FormattedMessage
+                                    {...messages.forThisSpriteMessage}
+                                />
+                            </label>
+                        </Box>}
+                    <Box className={styles.moreOptions}>
+                        <ComingSoonTooltip
+                            className={styles.moreOptionsAccordion}
+                            place="right"
+                            tooltipId="variable-options-accordion"
+                        >
+                            <div className={styles.moreOptionsText}>
+                                <FormattedMessage
+                                    {...messages.moreOptionsMessage}
+                                />
+                                <img
+                                    className={styles.moreOptionsIcon}
+                                    src={dropdownIcon}
+                                />
+                            </div>
+                        </ComingSoonTooltip>
+                    </Box>
+                </div> : null}
+
             <Box className={styles.buttonRow}>
                 <button
                     className={styles.cancelButton}
@@ -81,11 +132,13 @@ const PromptComponent = props => (
 );
 
 PromptComponent.propTypes = {
+    isStage: PropTypes.bool.isRequired,
     label: PropTypes.string.isRequired,
     onCancel: PropTypes.func.isRequired,
     onChange: PropTypes.func.isRequired,
     onKeyPress: PropTypes.func.isRequired,
     onOk: PropTypes.func.isRequired,
+    onOptionSelection: PropTypes.func.isRequired,
     placeholder: PropTypes.string,
     showMoreOptions: PropTypes.bool.isRequired,
     title: PropTypes.string.isRequired
diff --git a/src/components/sprite-info/sprite-info.css b/src/components/sprite-info/sprite-info.css
index 53758e65cc344038befbdae8066d41e14f2379c7..c835843994ce4ffb477a742fdd48c6461c288992 100644
--- a/src/components/sprite-info/sprite-info.css
+++ b/src/components/sprite-info/sprite-info.css
@@ -44,6 +44,10 @@
 }
 
 /* @todo: refactor radio divs to input */
+.radio-wrapper {
+    white-space: nowrap; /* make sure visibilty buttons don't wrap */
+}
+
 .radio {
     filter: saturate(0);
     cursor: pointer;
diff --git a/src/components/sprite-info/sprite-info.jsx b/src/components/sprite-info/sprite-info.jsx
index 09d5c96c7a0da7253f18b5652d22a4ae6d7c5272..37e18735a8c6b2bddbba1443f356b820f50ca321 100644
--- a/src/components/sprite-info/sprite-info.jsx
+++ b/src/components/sprite-info/sprite-info.jsx
@@ -176,7 +176,7 @@ class SpriteInfo extends React.Component {
                                 /> :
                                 null
                         }
-                        <div>
+                        <div className={styles.radioWrapper}>
                             <div
                                 className={classNames(
                                     styles.radio,
diff --git a/src/components/sprite-selector/sprite-list.jsx b/src/components/sprite-selector/sprite-list.jsx
index e8ab7f8d0cc583f25801617f53399ae0c78b10a1..a29912b79385183e8c49e0ac819ba5288ec3e761 100644
--- a/src/components/sprite-selector/sprite-list.jsx
+++ b/src/components/sprite-selector/sprite-list.jsx
@@ -71,6 +71,7 @@ const SpriteList = function (props) {
                                 [styles.raised]: isRaised,
                                 [styles.receivedBlocks]: receivedBlocks
                             })}
+                            dragPayload={sprite}
                             dragType={DragConstants.SPRITE}
                             id={sprite.id}
                             index={index}
diff --git a/src/containers/backpack.jsx b/src/containers/backpack.jsx
index 35fc11bf1655f2b40a0453ce55f12b04d9d1ad7f..aedf2f35da1c84187386aae3e5132d7fbfad9372 100644
--- a/src/containers/backpack.jsx
+++ b/src/containers/backpack.jsx
@@ -7,12 +7,14 @@ import {
     saveBackpackObject,
     deleteBackpackObject,
     soundPayload,
-    costumePayload
+    costumePayload,
+    spritePayload
 } from '../lib/backpack-api';
 import DragConstants from '../lib/drag-constants';
 
 import {connect} from 'react-redux';
 import storage from '../lib/storage';
+import VM from 'scratch-vm';
 
 class Backpack extends React.Component {
     constructor (props) {
@@ -45,7 +47,7 @@ class Backpack extends React.Component {
         }
     }
     componentWillReceiveProps (newProps) {
-        const dragTypes = [DragConstants.COSTUME, DragConstants.SOUND];
+        const dragTypes = [DragConstants.COSTUME, DragConstants.SOUND, DragConstants.SPRITE];
         // If `dragging` becomes true, record the drop area rectangle
         if (newProps.dragInfo.dragging && !this.props.dragInfo.dragging) {
             this.dropAreaRect = this.ref && this.ref.getBoundingClientRect();
@@ -83,10 +85,13 @@ class Backpack extends React.Component {
         case DragConstants.SOUND:
             payloader = soundPayload;
             break;
+        case DragConstants.SPRITE:
+            payloader = spritePayload;
+            break;
         }
         if (!payloader) return;
 
-        payloader(dragInfo.payload)
+        payloader(dragInfo.payload, this.props.vm)
             .then(payload => saveBackpackObject({
                 host: this.props.host,
                 token: this.props.token,
@@ -152,7 +157,8 @@ Backpack.propTypes = {
     }),
     host: PropTypes.string,
     token: PropTypes.string,
-    username: PropTypes.string
+    username: PropTypes.string,
+    vm: PropTypes.instanceOf(VM)
 };
 
 const getTokenAndUsername = state => {
diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index 985211b06a6973bde35948764792eeb7816ea9a0..ca327d2cefc8f538fbef34ca05758a86eb3aef06 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -328,9 +328,13 @@ class Blocks extends React.Component {
     handlePromptStart (message, defaultValue, callback, optTitle, optVarType) {
         const p = {prompt: {callback, message, defaultValue}};
         p.prompt.title = optTitle ? optTitle :
-            this.ScratchBlocks.VARIABLE_MODAL_TITLE;
+            this.ScratchBlocks.Msg.VARIABLE_MODAL_TITLE;
+        p.prompt.varType = typeof optVarType === 'string' ?
+            optVarType : this.ScratchBlocks.SCALAR_VARIABLE_TYPE;
         p.prompt.showMoreOptions =
-            optVarType !== this.ScratchBlocks.BROADCAST_MESSAGE_VARIABLE_TYPE;
+            optVarType !== this.ScratchBlocks.BROADCAST_MESSAGE_VARIABLE_TYPE &&
+            p.prompt.title !== this.ScratchBlocks.Msg.RENAME_VARIABLE_MODAL_TITLE &&
+            p.prompt.title !== this.ScratchBlocks.Msg.RENAME_LIST_MODAL_TITLE;
         this.setState(p);
     }
     handleConnectionModalStart (extensionId) {
@@ -345,8 +349,10 @@ class Blocks extends React.Component {
     handleStatusButtonUpdate (extensionId, status) {
         this.ScratchBlocks.updateStatusButton(this.workspace, extensionId, status);
     }
-    handlePromptCallback (data) {
-        this.state.prompt.callback(data);
+    handlePromptCallback (input, optionSelection) {
+        this.state.prompt.callback(input, optionSelection,
+            (optionSelection === 'local') ? [] :
+                this.props.vm.runtime.getAllVarNamesOfType(this.state.prompt.varType));
         this.handlePromptClose();
     }
     handlePromptClose () {
@@ -385,6 +391,7 @@ class Blocks extends React.Component {
                 />
                 {this.state.prompt ? (
                     <Prompt
+                        isStage={vm.runtime.getEditingTarget().isStage}
                         label={this.state.prompt.message}
                         placeholder={this.state.prompt.defaultValue}
                         showMoreOptions={this.state.prompt.showMoreOptions}
diff --git a/src/containers/prompt.jsx b/src/containers/prompt.jsx
index a798b02ed780ea8a3dbe5a31bad4e17aa3b66226..72c8ad8a376ff22ecef130e875053ed79c2a435b 100644
--- a/src/containers/prompt.jsx
+++ b/src/containers/prompt.jsx
@@ -8,19 +8,21 @@ class Prompt extends React.Component {
         super(props);
         bindAll(this, [
             'handleOk',
+            'handleOptionSelection',
             'handleCancel',
             'handleChange',
             'handleKeyPress'
         ]);
         this.state = {
-            inputValue: ''
+            inputValue: '',
+            optionSelection: null
         };
     }
     handleKeyPress (event) {
         if (event.key === 'Enter') this.handleOk();
     }
     handleOk () {
-        this.props.onOk(this.state.inputValue);
+        this.props.onOk(this.state.inputValue, this.state.optionSelection);
     }
     handleCancel () {
         this.props.onCancel();
@@ -28,9 +30,13 @@ class Prompt extends React.Component {
     handleChange (e) {
         this.setState({inputValue: e.target.value});
     }
+    handleOptionSelection (e) {
+        this.setState({optionSelection: e.target.value});
+    }
     render () {
         return (
             <PromptComponent
+                isStage={this.props.isStage}
                 label={this.props.label}
                 placeholder={this.props.placeholder}
                 showMoreOptions={this.props.showMoreOptions}
@@ -39,12 +45,14 @@ class Prompt extends React.Component {
                 onChange={this.handleChange}
                 onKeyPress={this.handleKeyPress}
                 onOk={this.handleOk}
+                onOptionSelection={this.handleOptionSelection}
             />
         );
     }
 }
 
 Prompt.propTypes = {
+    isStage: PropTypes.bool.isRequired,
     label: PropTypes.string.isRequired,
     onCancel: PropTypes.func.isRequired,
     onOk: PropTypes.func.isRequired,
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index 1d637330acce4a4410f1f6ecd840089c86febfc6..5f9fef8db723287d70b68669a858050c09edf15a 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -135,6 +135,12 @@ class TargetPane extends React.Component {
         if (dragInfo.dragType === DragConstants.SPRITE) {
             // Add one to both new and target index because we are not counting/moving the stage
             this.props.vm.reorderTarget(dragInfo.index + 1, dragInfo.newIndex + 1);
+        } else if (dragInfo.dragType === DragConstants.BACKPACK_SPRITE) {
+            // TODO storage does not have a way of loading zips right now, and may never need it.
+            // So for now just grab the zip manually.
+            fetch(dragInfo.payload.bodyUrl)
+                .then(response => response.arrayBuffer())
+                .then(sprite3Zip => this.props.vm.addSprite(sprite3Zip));
         } else if (targetId) {
             // Something is being dragged over one of the sprite tiles or the backdrop.
             // Dropping assets like sounds and costumes duplicate the asset on the
diff --git a/src/lib/backpack-api.js b/src/lib/backpack-api.js
index 9a2b19e95979a57329cbcd87dac60b895fdb18bf..f0c51f14040ced7823c226521dd792b4cf639f65 100644
--- a/src/lib/backpack-api.js
+++ b/src/lib/backpack-api.js
@@ -1,6 +1,7 @@
 import xhr from 'xhr';
 import costumePayload from './backpack/costume-payload';
 import soundPayload from './backpack/sound-payload';
+import spritePayload from './backpack/sprite-payload';
 
 const getBackpackContents = ({
     host,
@@ -19,9 +20,13 @@ const getBackpackContents = ({
             return reject();
         }
         // Add a new property for the full thumbnail url, which includes the host.
+        // Also include a full body url for loading sprite zips
         // TODO retreiving the images through storage would allow us to remove this.
         return resolve(response.body.map(item => (
-            Object.assign({}, item, {thumbnailUrl: `${host}/${item.thumbnail}`})
+            Object.assign({}, item, {
+                thumbnailUrl: `${host}/${item.thumbnail}`,
+                bodyUrl: `${host}/${item.body}`
+            })
         )));
     });
 });
@@ -72,5 +77,6 @@ export {
     saveBackpackObject,
     deleteBackpackObject,
     costumePayload,
-    soundPayload
+    soundPayload,
+    spritePayload
 };
diff --git a/src/lib/backpack/sprite-payload.js b/src/lib/backpack/sprite-payload.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9dea7f22ab4cf9933463540903dada2c4a6206c
--- /dev/null
+++ b/src/lib/backpack/sprite-payload.js
@@ -0,0 +1,24 @@
+import jpegThumbnail from './jpeg-thumbnail';
+import storage from '../storage';
+
+const spritePayload = (sprite, vm) => vm.exportSprite(
+    sprite.id,
+    'base64'
+).then(zippedSprite => {
+    const payload = {
+        type: 'sprite',
+        name: sprite.name,
+        mime: 'application/zip',
+        body: zippedSprite,
+        // Filled in below
+        thumbnail: ''
+    };
+
+    const costumeDataUrl = storage.get(sprite.costume.assetId).encodeDataURI();
+    return jpegThumbnail(costumeDataUrl).then(thumbnail => {
+        payload.thumbnail = thumbnail.replace('data:image/jpeg;base64,', '');
+        return payload;
+    });
+});
+
+export default spritePayload;
diff --git a/src/lib/make-toolbox-xml.js b/src/lib/make-toolbox-xml.js
index 2fea2f0cb33964845f12a628c9d9b59fa4a06beb..1c2a0ae1936d2ef2d373ba87437bc696e80d3467 100644
--- a/src/lib/make-toolbox-xml.js
+++ b/src/lib/make-toolbox-xml.js
@@ -553,7 +553,7 @@ const operators = function () {
             </value>
             <value name="OPERAND2">
                 <shadow type="text">
-                    <field name="TEXT">100</field>
+                    <field name="TEXT">50</field>
                 </shadow>
             </value>
         </block>
@@ -565,7 +565,7 @@ const operators = function () {
             </value>
             <value name="OPERAND2">
                 <shadow type="text">
-                    <field name="TEXT">100</field>
+                    <field name="TEXT">50</field>
                 </shadow>
             </value>
         </block>
@@ -577,7 +577,7 @@ const operators = function () {
             </value>
             <value name="OPERAND2">
                 <shadow type="text">
-                    <field name="TEXT">100</field>
+                    <field name="TEXT">50</field>
                 </shadow>
             </value>
         </block>