diff --git a/.gitignore b/.gitignore
index ca4d940..1d5cbb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 *.swp
 test/lib/*
+.DS_Store
 
 logs
 
diff --git a/img/ask-bottom.png b/img/ask-bottom.png
new file mode 100644
index 0000000..9823a43
Binary files /dev/null and b/img/ask-bottom.png differ
diff --git a/img/ask-button.png b/img/ask-button.png
new file mode 100644
index 0000000..713927a
Binary files /dev/null and b/img/ask-button.png differ
diff --git a/img/playerStartFlag.png b/img/playerStartFlag.png
index 11a8e72..f2211d1 100644
Binary files a/img/playerStartFlag.png and b/img/playerStartFlag.png differ
diff --git a/js/Reporter.js b/js/Reporter.js
index a6acd66..c55f0d2 100644
--- a/js/Reporter.js
+++ b/js/Reporter.js
@@ -19,7 +19,6 @@ var Reporter = function(data) {
     this.cmd = data.cmd;
     this.color = data.color;
     this.isDiscrete = data.isDiscrete;
-    this.label = data.label;
     this.mode = data.mode;
     this.param = data.param;
     this.sliderMin = data.sliderMin;
@@ -35,11 +34,19 @@ var Reporter = function(data) {
     this.slider = null; // slider jQ element
 };
 
+Reporter.prototype.determineReporterLabel = function() {
+  if (this.target === 'Stage') {
+    return this.param;
+  } else {
+    return this.target + ': ' + this.param;
+  }
+}
+
 Reporter.prototype.attach = function(scene) {
     switch (this.mode) {
         case 1: // Normal
         case 3: // Slider
-            this.el = $('<div class="reporter-normal">' + this.label + '</div>');
+            this.el = $('<div class="reporter-normal">' + this.determineReporterLabel() + '</div>');
             this.valueEl = $('<div class="reporter-inset">null</div>');
             this.el.append(this.valueEl);
             if (this.mode == 3) {
diff --git a/js/Sprite.js b/js/Sprite.js
index 026d17e..07d7621 100644
--- a/js/Sprite.js
+++ b/js/Sprite.js
@@ -73,7 +73,14 @@ var Sprite = function(data) {
     this.talkBubbleStyler = null;
     this.talkBubbleOn = false;
 
+    // HTML element for the ask bubbles
+    this.askInput = null;
+    this.askInputField = null;
+    this.askInputButton = null;
+    this.askInputOn = false;
+
     // Internal variables used for rendering meshes.
+    this.askAnswer = null; //this is a private variable
     this.textures = [];
     this.materials = [];
     this.geometries = [];
@@ -142,14 +149,26 @@ Sprite.prototype.attach = function(scene) {
     this.updateVisible();
     this.updateTransform();
 
-    this.talkBubble = $('<div class="bubble-container"></div>');
-    this.talkBubble.css('display', 'none');
-    this.talkBubbleBox = $('<div class="bubble"></div>');
-    this.talkBubbleStyler = $('<div class="bubble-say"></div>');
-    this.talkBubble.append(this.talkBubbleBox);
-    this.talkBubble.append(this.talkBubbleStyler);
+    if (! this.isStage) {
+      this.talkBubble = $('<div class="bubble-container"></div>');
+      this.talkBubble.css('display', 'none');
+      this.talkBubbleBox = $('<div class="bubble"></div>');
+      this.talkBubbleStyler = $('<div class="bubble-say"></div>');
+      this.talkBubble.append(this.talkBubbleBox);
+      this.talkBubble.append(this.talkBubbleStyler);
+    }
+
+    this.askInput = $('<div class="ask-container"></div>');
+    this.askInput.css('display', 'none');
+    this.askInputField = $('<div class="ask-field"></div>');
+    this.askInputTextField = $('<input class="ask-text-field"></input>');
+    this.askInputField.append(this.askInputTextField);
+    this.askInputButton = $('<div class="ask-button"></div>');
+    this.askInput.append(this.askInputField);
+    this.askInput.append(this.askInputButton);
 
     runtime.scene.append(this.talkBubble);
+    runtime.scene.append(this.askInput);
 };
 
 // Load sounds from the server and buffer them
@@ -254,20 +273,22 @@ Sprite.prototype.onClick = function(evt) {
 };
 
 Sprite.prototype.setVisible = function(v) {
+  if (v === true || v === false) {
     this.visible = v;
     this.updateVisible();
+  }
 };
 
 Sprite.prototype.updateLayer = function() {
     $(this.mesh).css('z-index', this.z);
-    if (this.talkBubble) this.talkBubble.css('z-index', this.z);
+    if (this.talkBubble) $(this.talkBubble).css('z-index', this.z);
+    if (this.askInput) this.askInput.css('z-index', this.z);
 };
 
 Sprite.prototype.updateVisible = function() {
     $(this.mesh).css('display', this.visible ? 'inline' : 'none');
-    if (this.talkBubbleOn) {
-        this.talkBubble.css('display', this.visible ? 'inline-block' : 'none');
-    }
+    if (this.talkBubbleOn) this.talkBubble.css('display', this.visible ? 'inline-block' : 'none');
+    if (this.askInputOn) this.askInput.css('display', this.visible ? 'inline-block' : 'none');
 };
 
 Sprite.prototype.updateTransform = function() {
@@ -347,13 +368,21 @@ Sprite.prototype.showBubble = function(text, type) {
     this.talkBubble.css('left', xy[0] + 'px');
     this.talkBubble.css('top', xy[1] + 'px');
 
-
+    this.talkBubble.removeClass('say-think-border');
+    this.talkBubble.removeClass('ask-border');
+    
     this.talkBubbleStyler.removeClass('bubble-say');
     this.talkBubbleStyler.removeClass('bubble-think');
+    this.talkBubbleStyler.removeClass('bubble-ask');
     if (type == 'say') {
+        this.talkBubbleBox.addClass('say-think-border');
         this.talkBubbleStyler.addClass('bubble-say');
     } else if (type == 'think') {
+        this.talkBubbleBox.addClass('say-think-border');
         this.talkBubbleStyler.addClass('bubble-think');
+    } else if (type == 'doAsk') {
+        this.talkBubbleBox.addClass('ask-border');
+        this.talkBubbleStyler.addClass('bubble-ask');
     }
 
     if (this.visible) {
@@ -367,6 +396,25 @@ Sprite.prototype.hideBubble = function() {
     this.talkBubble.css('display', 'none');
 };
 
+Sprite.prototype.showAsk = function() {
+    this.askInputOn = true;
+    this.askInput.css('z-index', this.z);
+    this.askInput.css('left', '15px');
+    this.askInput.css('right', '15px');
+    this.askInput.css('bottom', '7px');
+    this.askInput.css('height', '25px');
+
+    if (this.visible) {
+        this.askInput.css('display', 'inline-block');
+        this.askInputTextField.focus();
+    }
+};
+
+Sprite.prototype.hideAsk = function() {
+    this.askInputOn = false;
+    this.askInput.css('display', 'none');
+};
+
 Sprite.prototype.setXY = function(x, y) {
     this.scratchX = x;
     this.scratchY = y;
diff --git a/js/Stage.js b/js/Stage.js
index c425e10..8146e93 100644
--- a/js/Stage.js
+++ b/js/Stage.js
@@ -33,6 +33,7 @@ var Stage = function(data) {
     this.lineCanvas.width = 480;
     this.lineCanvas.height = 360;
     this.lineCache = this.lineCanvas.getContext('2d');
+    this.isStage = true;
 
     Sprite.call(this, data);
 };
diff --git a/js/primitives/LooksPrims.js b/js/primitives/LooksPrims.js
index e56f646..b63c7f2 100644
--- a/js/primitives/LooksPrims.js
+++ b/js/primitives/LooksPrims.js
@@ -43,6 +43,9 @@ LooksPrims.prototype.addPrimsTo = function(primTable) {
     primTable['setGraphicEffect:to:']    = this.primSetEffect;
     primTable['filterReset']             = this.primClearEffects;
 
+    primTable['doAsk']              = this.primDoAsk;
+    primTable['answer']             = this.primAnswer;
+
     primTable['say:'] = function(b) { showBubble(b, 'say'); };
     primTable['say:duration:elapsed:from:'] = function(b) { showBubbleAndWait(b, 'say'); };
     primTable['think:'] = function(b) { showBubble(b, 'think'); };
@@ -170,6 +173,17 @@ LooksPrims.prototype.primClearEffects = function(b) {
     s.updateFilters();
 };
 
+LooksPrims.prototype.primDoAsk= function(b) {
+    showBubble(b, "doAsk");
+    var s = interp.targetSprite();
+    if (s != null) s.showAsk();
+};
+
+LooksPrims.prototype.primAnswer = function() {
+    var s = interp.targetSprite();
+    return ((s != null) ? s.answer : undefined);
+};
+
 var showBubble = function(b, type) {
     var s = interp.targetSprite();
     if (s != null) s.showBubble(interp.arg(b, 0), type);
diff --git a/player.css b/player.css
index 3fcff6c..40ca47e 100644
--- a/player.css
+++ b/player.css
@@ -398,7 +398,7 @@ button#trigger-stop:hover {
 }
 
 /* Say/think bubble styles */
- .bubble-container {
+.bubble-container {
     position: absolute;
 }
 .bubble {
@@ -407,7 +407,6 @@ button#trigger-stop:hover {
     max-width: 120px;
     min-width: 40px;
     padding: 6px 11px 6px 11px;
-    border: 3px solid rgb(160, 160, 160);
     border-radius: 10px;
     background: #fff;
     font-family: sans-serif;
@@ -416,6 +415,20 @@ button#trigger-stop:hover {
     color: #000;
     text-align: center;
 }
+.bubble.say-think-border {
+    border: 3px solid rgb(160, 160, 160);
+}
+.bubble.ask-border, .ask-container {
+    border: 3px solid rgb(74, 173, 222);
+}
+.bubble-ask {
+    position: absolute;
+    margin-top: -3px;
+    margin-left: 8px;
+    width: 44px;
+    height: 18px;
+    background: url(img/ask-bottom.png) transparent no-repeat;
+}
 .bubble-say {
     position: absolute;
     margin-top: -3px;
@@ -432,3 +445,33 @@ button#trigger-stop:hover {
     height: 19px;
     background: url(img/think-bottom.png) transparent no-repeat;
 }
+.ask-container {
+    position: absolute;
+    display: inline-block;
+    padding: 5px 0px 0px 5px;
+    border-radius: 5px;
+    background: #fff;
+    font-family: sans-serif;
+    font-weight: bold;
+    font-size: 14px;
+    color: #000;
+}
+.ask-container .ask-field .ask-text-field {
+    width: 405px;
+    height: 16px;
+    font-family: sans-serif;
+    font-weight: light;
+    font-size: 12px;
+    background: #EAEAEA;
+}
+
+.ask-container .ask-button {
+    position: absolute;
+    right: 2px;
+    top: 2px;
+    width: 25px;
+    height: 25px;
+    background: url(img/ask-button.png) transparent no-repeat;
+}
+
+
diff --git a/test/artifacts/IOMock.js b/test/artifacts/IOMock.js
new file mode 100644
index 0000000..6a7a118
--- /dev/null
+++ b/test/artifacts/IOMock.js
@@ -0,0 +1,25 @@
+'use strict';
+
+var ioMock = function() {
+  var args = createArgs(arguments);
+
+  function getArgs(argKey) {
+    return ((argKey in args) ? args[argKey] : null);
+  }
+
+  function createArgs(methodArgs) {
+    var args = {};
+    if (methodArgs.length) {
+      _.each(methodArgs, function(newObject) {
+        _.each(newObject, function(value, key) {
+          args[key] = value;
+        });
+      });
+    }
+    return args;
+  }
+
+  return {
+    'getCount' : function() { return getArgs('getCount'); }
+  }
+};
diff --git a/test/artifacts/TargetMock.js b/test/artifacts/TargetMock.js
index 9121a00..8071a39 100644
--- a/test/artifacts/TargetMock.js
+++ b/test/artifacts/TargetMock.js
@@ -2,7 +2,9 @@
 
 var targetMock = function() {
   return {
-    'showBubble' : function() {}
+    'showBubble' : function() {},
+    'showAsk' : function() {},
+    'answer' : 22
   };
 
 }
diff --git a/test/artifacts/ask-artifact.js b/test/artifacts/ask-artifact.js
index 4f0852a..654a07d 100644
--- a/test/artifacts/ask-artifact.js
+++ b/test/artifacts/ask-artifact.js
@@ -1,7 +1,10 @@
-'use strict';
-
 var sensingData = {
   "objName": "Stage",
+  "variables": [{
+      "name": "myAnswer",
+      "value": 0,
+      "isPersistent": false
+    }],
   "costumes": [{
       "costumeName": "backdrop1",
       "baseLayerID": -1,
@@ -16,6 +19,15 @@ var sensingData = {
   "videoAlpha": 0.5,
   "children": [{
       "objName": "Sprite1",
+      "variables": [{
+          "name": "myAnswer2",
+          "value": 0,
+          "isPersistent": false
+        }, {
+          "name": "answer",
+          "value": 0,
+          "isPersistent": false
+        }],
       "scripts": [[42, 40.5, [["whenGreenFlag"], ["doAsk", "What's your name?"]]],
         [44.5,
           155.5,
diff --git a/test/artifacts/reporterValues.js b/test/artifacts/reporterValues.js
new file mode 100644
index 0000000..484b990
--- /dev/null
+++ b/test/artifacts/reporterValues.js
@@ -0,0 +1,91 @@
+'use Strict;'
+
+var ReporterValues = function() {
+  return {
+    'getStageVariables': function() {
+      return {
+        'cmd' : "getVar:",
+        'color' : 15629590,
+        'isDiscrete' :  true,
+        'mode' : 1,
+        'param' : "myAnswer",
+        'sliderMax' : 100,
+        'sliderMin' : 0,
+        'target' : "Stage",
+        'visible' : true,
+        'x' : 5,
+        'y' : 5,
+      };
+    }
+  }
+};
+/*
+cmd
+  "getVar:"
+  
+color
+  15629590
+  
+isDiscrete
+  true
+  
+mode
+  1
+  
+param
+  "myAnswer2"
+  
+sliderMax
+  100
+  
+sliderMin
+  0
+  
+target
+  "Sprite1"
+  
+visible
+  true
+  
+x
+  5
+  
+y
+  32
+*/
+
+/*
+  
+cmd
+  "getVar:"
+  
+color
+  15629590
+  
+isDiscrete
+  true
+  
+mode
+  1
+  
+param
+  "answer"
+  
+sliderMax
+  100
+  
+sliderMin
+  0
+  
+target
+  "Sprite1"
+  
+visible
+  true
+  
+x
+  5
+  
+y
+  59
+*/
diff --git a/test/unit/looksPrimitiveSpec.js b/test/unit/looksPrimitiveSpec.js
index cadbc6e..a46f747 100644
--- a/test/unit/looksPrimitiveSpec.js
+++ b/test/unit/looksPrimitiveSpec.js
@@ -1,23 +1,65 @@
 /* jasmine specs for primitives/LooksPrims.js go here */
 
 describe ('LooksPrims', function() {
-  var looksPrims;
+  var looksPrims, targetSpriteMock;
   beforeEach(function() {
     looksPrims = LooksPrims;
+    targetSpriteMock = targetMock();
   });
 
-  describe('showBubble', function(){
-    var sayBlock, targetSpriteMock;
+  describe('showBubble for Say', function(){
+    var sayBlock;
     beforeEach(function() {
       sayBlock = {'args': ['what to say']};
-      targetSpriteMock = targetMock();
       interp = interpreterMock({'targetSprite': targetSpriteMock }, {'arg': sayBlock});
-
     });
-    it('should return do something', function() {
+
+    it('should call the showBubble method on the targetedSprite', function() {
       spyOn(targetSpriteMock, "showBubble");
       showBubble(sayBlock, "say");
       expect(targetSpriteMock.showBubble).toHaveBeenCalled;
     });
   });
+
+  describe('showBubble for Think', function(){
+    var thinkBlock;
+    beforeEach(function() {
+      thinkBlock = {'args': ['what to think']};
+      interp = interpreterMock({'targetSprite': targetSpriteMock }, {'arg': thinkBlock});
+    });
+
+    it('should call the showBubble method on the targetedSprite', function() {
+      spyOn(targetSpriteMock, "showBubble");
+      showBubble(thinkBlock, "think");
+      expect(targetSpriteMock.showBubble).toHaveBeenCalled;
+    });
+  });
+
+
+  describe('showBubble for Ask', function(){
+    var askBlock;
+    beforeEach(function() {
+      askBlock = {'args': 'what to ask'};
+      interp = interpreterMock({'targetSprite': targetSpriteMock }, {'arg': askBlock});
+
+    });
+
+    it('should call the showBubble method on the targetedSprite', function() {
+      spyOn(targetSpriteMock, "showBubble");
+      spyOn(targetSpriteMock, "showAsk");
+      looksPrims.prototype.primDoAsk(askBlock);
+      expect(targetSpriteMock.showBubble).toHaveBeenCalled;
+      expect(targetSpriteMock.showAsk).toHaveBeenCalled;
+    });
+  });
+
+  describe('primAnswer', function(){
+    beforeEach(function() {
+      interp = interpreterMock({'targetSprite': targetSpriteMock });
+    });
+
+    it('should return the answer variable from the targetedSprite', function() {
+      expect(looksPrims.prototype.primAnswer()).toBe(22);
+    });
+  });
 });
diff --git a/test/unit/reporterSpec.js b/test/unit/reporterSpec.js
new file mode 100644
index 0000000..c879f58
--- /dev/null
+++ b/test/unit/reporterSpec.js
@@ -0,0 +1,96 @@
+/* jasmine specs for Reporter.js go here */
+
+describe ('Reporter', function() {
+  var reporter, reporterValues;
+
+  beforeEach(function() {
+    reporter = Reporter;
+    reporterValues = new ReporterValues();
+  });
+
+  describe('Instantization variables', function() {
+    var initReporter;
+    beforeEach(function() {
+      io = new ioMock({'getCount': 4});
+      initReporter = new reporter(reporterValues.getStageVariables());
+    });
+
+    describe('Reporter Variables', function() {
+      it('should have a cmd variable', function() {
+        expect(initReporter.cmd).toBe('getVar:');
+      });
+
+      it('should have a color variable', function() {
+        expect(initReporter.color).toBe(15629590);
+      });
+
+      it('should have a isDiscrete variable', function() {
+        expect(initReporter.isDiscrete).toBe(true);
+      });
+
+      it('should have a mode variable', function() {
+        expect(initReporter.mode).toBe(1);
+      });
+
+      it('should have a param variable', function() {
+        expect(initReporter.param).toBe('myAnswer');
+      });
+
+      it('should have a sliderMax variable', function() {
+        expect(initReporter.sliderMax).toBe(100);
+      });
+
+      it('should have a sliderMin variable', function() {
+        expect(initReporter.sliderMin).toBe(0);
+      });
+
+      it('should have a target variable', function() {
+        expect(initReporter.target).toBe('Stage');
+      });
+
+      it('should have a visible variable', function() {
+        expect(initReporter.visible).toBe(true);
+      });
+
+      it('should have a x variable', function() {
+        expect(initReporter.x).toBe(5);
+      });
+
+      it('should have a y variable', function() {
+        expect(initReporter.y).toBe(5);
+      });
+
+      it('should have a z variable', function() {
+        expect(initReporter.z).toBe(4);
+      });
+
+      it('should have an el variable', function() {
+        expect(initReporter.el).toBe(null);
+      });
+
+      it('should have an valueEl variable', function() {
+        expect(initReporter.valueEl).toBe(null);
+      });
+
+      it('should have an slider variable', function() {
+        expect(initReporter.slider).toBe(null);
+      });
+    });
+  });
+  describe('determineReporterLabel', function() {
+
+    it('should return a stage variable', function() {
+      reporter.prototype.target = "Stage";
+      reporter.prototype.param = "myAnswer";
+      expect(reporter.prototype.determineReporterLabel()).toBe('myAnswer');
+    });
+
+    it('should return a sprite variable', function() {
+      reporter.prototype.target = "Sprite 1";
+      reporter.prototype.param = "localAnswer";
+      expect(reporter.prototype.determineReporterLabel()).toBe('Sprite 1: localAnswer');
+
+    });
+
+  });
+});
diff --git a/test/unit/spriteSpec.js b/test/unit/spriteSpec.js
new file mode 100644
index 0000000..feeb11c
--- /dev/null
+++ b/test/unit/spriteSpec.js
@@ -0,0 +1,352 @@
+/* jasmine specs for Sprite.js go here */
+
+describe ('Sprite', function() {
+  var sprite;
+
+
+  beforeEach(function() {
+    sprite = Sprite;
+  });
+
+  describe('Instantization variables', function() {
+    var initSprite;
+    beforeEach(function() {
+      var spriteObject = sensingData.children[0];
+      initSprite = new sprite(spriteObject);
+    });
+
+    describe('Sprite Variables', function() {
+      it('should have a visible variable', function() {
+        expect(initSprite.visible).toBe(true);
+      });
+    });
+
+    describe('Pen Variables', function() {
+      it('should have a penIsDown variable', function() {
+        expect(initSprite.penIsDown).toBe(false);
+      });
+
+      it('should have a penWidth variable', function() {
+        expect(initSprite.penWidth).toBe(1);
+      });
+
+      it('should have a penHue variable', function() {
+        expect(initSprite.penHue).toBe(120);
+      });
+
+      it('should have a penShade variable', function() {
+        expect(initSprite.penShade).toBe(50);
+      });
+
+      it('should have a penColorCache variable', function() {
+        expect(initSprite.penColorCache).toBe(0x0000FF);
+      });
+    });
+
+    describe('Ask Bubble', function() {
+      it('should have an askInput variable', function() {
+        expect(initSprite.askInput).toBe(null);
+      });
+
+      it('should have an askInputBox variable', function() {
+        expect(initSprite.askInputField).toBe(null);
+      });
+
+      it('should have an askInputStyler variable', function() {
+        expect(initSprite.askInputButton).toBe(null);
+      });
+
+      it('should have an askInputOn variable', function() {
+        expect(initSprite.askInputOn).toBe(false);
+      });
+
+      it('should have an answer variable', function() {
+        expect(initSprite.askAnswer).toBe(null);
+      });
+    });
+  })
+
+  describe('showBubble', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      spriteProto.visible = true;
+      setFixtures('<div class="bubble-container"></div>');
+      spriteProto.talkBubble = $('.bubble-container');
+      spriteProto.talkBubble.css('display', 'none');
+      spriteProto.talkBubbleBox = $('<div class="bubble"></div>');
+      spriteProto.talkBubbleStyler = $('<div class="bubble-say"></div>');
+      spriteProto.talkBubble.append(spriteProto.talkBubbleBox);
+      spriteProto.talkBubble.append(spriteProto.talkBubbleStyler);
+    });
+
+    describe('Say', function(){
+      it('should call the showBubble method on the Sprite', function() {
+        var text = "What to say";
+        spyOn(spriteProto, "getTalkBubbleXY").andReturn([50,50]);;
+        spriteProto.showBubble(text, "say");
+        expect($('.bubble').html()).toBe(text);
+        expect($('.bubble-say').hasClass('bubble-say')).toBe(true);
+        expect($('.bubble').hasClass('say-think-border')).toBe(true);
+        expect($('.bubble-container').css('display')).toBe('inline-block');
+      });
+    });
+
+    describe('Think', function(){
+      it('should call the showBubble method on the Sprite', function() {
+        var text = "What to think";
+        spyOn(spriteProto, "getTalkBubbleXY").andReturn([50,50]);;
+        spriteProto.showBubble(text, "think");
+        expect($('.bubble').html()).toBe(text);
+        expect($('.bubble-think').hasClass('bubble-think')).toBe(true);
+        expect($('.bubble').hasClass('say-think-border')).toBe(true);
+        expect($('.bubble-container').css('display')).toBe('inline-block');
+      });
+    });
+
+    describe('Ask', function(){
+      it('should call the showBubble method on the Sprite', function() {
+        var text = "What to Ask";
+        spyOn(spriteProto, "getTalkBubbleXY").andReturn([50,50]);;
+        spriteProto.showBubble(text, "doAsk");
+        expect($('.bubble').html()).toBe(text);
+        expect($('.bubble-ask').hasClass('bubble-ask')).toBe(true);
+        expect($('.bubble').hasClass('ask-border')).toBe(true);
+        expect($('.bubble-container').css('display')).toBe('inline-block');
+      });
+    });
+
+    describe('Any Bubble with visible false', function(){
+      it('should call the showBubble method on the Sprite and not display it', function() {
+        spriteProto.visible = false;
+        var text = "What to Ask";
+        spyOn(spriteProto, "getTalkBubbleXY").andReturn([50,50]);;
+        spriteProto.showBubble(text, "doAsk");
+        expect($('.bubble').html()).toBe(text);
+        expect($('.bubble-ask').hasClass('bubble-ask')).toBe(true);
+        expect($('.bubble').hasClass('ask-border')).toBe(true);
+        expect($('.bubble-container').css('display')).toBe('none');
+      });
+    });
+  });
+
+  describe('hideBubble', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      setFixtures('<div class="bubble-container"></div>');
+      spriteProto.talkBubble = $('.bubble-container');
+      spriteProto.talkBubble.css('display', 'inline');
+    });
+
+    it('should hide the bubble', function() {
+      spriteProto.hideBubble();
+      expect($('.bubble-container').css('display')).toBe('none');
+      expect(spriteProto.talkBubbleOn).toBe(false);
+
+    });
+  });
+
+  describe('showAsk', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      spriteProto.visible = true;
+      spriteProto.z = 22;
+      setFixtures('<div class="ask-container"></div>');
+      spriteProto.askInput= $('.ask-container');
+      spriteProto.askInput.css('display','none');
+      spriteProto.askInput.css('position','relative');
+      spriteProto.askInputField = $('<div class="ask-input"></div>');
+      spriteProto.askInputTextField = $('<input class="ask-text-field"></input>');
+      spriteProto.askInputField.append(spriteProto.askInputTextField);
+      spriteProto.askInputButton = $('<div class="ask-button"></div>');
+      spriteProto.askInput.append(spriteProto.askInputField);
+      spriteProto.askInput.append(spriteProto.askInputButton);
+    });
+
+    it('should show the ask input if visible is true', function() {
+      spriteProto.showAsk();
+      expect($('.ask-container').css('display')).toBe('inline-block');
+      expect($('.ask-container').css('z-index')).toBe('22');
+      expect($('.ask-container').css('left')).toBe('15px');
+      expect($('.ask-container').css('right')).toBe('15px');
+      expect($('.ask-container').css('bottom')).toBe('7px');
+      expect($('.ask-container').css('height')).toBe('25px');
+      expect($('.ask-container').css('height')).toBe('25px');
+      expect($('.ask-text-field').is(':focus')).toBe(true);
+      expect(spriteProto.askInputOn).toBe(true);
+    });
+
+    it('should not show the ask input if visible is false', function() {
+      spriteProto.visible = false;
+      spriteProto.showAsk();
+      expect($('.ask-container').css('display')).toBe('none');
+      expect($('.ask-text-field').is(':focus')).toBe(false);
+    });
+  });
+
+  describe('hideAsk', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      setFixtures('<div class="ask-container"></div>');
+      spriteProto.askInput = $('.ask-container');
+      spriteProto.askInput.css('display', 'inline');
+    });
+
+    it('should hide the ask input', function() {
+      spriteProto.hideAsk();
+      expect($('.ask-container').css('display')).toBe('none');
+      expect(spriteProto.askInputOn).toBe(false);
+
+    });
+  });
+
+  describe('updateLayer', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      setFixtures('<img class="mesh"></img><div class="bubble-container"></div><div class="ask-container"></div>');
+      spriteProto.talkBubble = $('.bubble-container');
+      spriteProto.talkBubble.css('position', 'relative');
+      spriteProto.askInput = $('.ask-container');
+      spriteProto.askInput.css('position', 'relative');
+      spriteProto.mesh = $('.mesh');
+      spriteProto.mesh.css('position', 'relative');
+      spriteProto.z = 22;
+    });
+
+    it('should update the mesh z-index', function() {
+      expect($('.mesh').css('z-index')).toBe('auto');
+      spriteProto.updateLayer();
+      expect($('.mesh').css('z-index')).toBe('22');
+    });
+
+    it('should update the talkBubble z-index', function() {
+      expect($('.bubble-container').css('z-index')).toBe('auto');
+      spriteProto.updateLayer();
+      expect($('.bubble-container').css('z-index')).toBe('22');
+    });
+
+    it('should update the askInput z-index', function() {
+      expect($('.ask-container').css('z-index')).toBe('auto');
+      spriteProto.updateLayer();
+      expect($('.ask-container').css('z-index')).toBe('22');
+    });
+  });
+
+  describe('updateVisible', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      setFixtures('<img class="mesh"></img><div class="bubble-container"></div><div class="ask-container"></div>');
+      spriteProto.talkBubble = $('.bubble-container');
+      spriteProto.talkBubble.css('display', 'none');
+      spriteProto.askInput = $('.ask-container');
+      spriteProto.askInput.css('display', 'none');
+      spriteProto.mesh = $('.mesh');
+      spriteProto.mesh.css('display', 'none');
+    });
+
+    describe('mesh', function() {
+      it('should update the mesh display on false', function() {
+        expect($('.mesh').css('display')).toBe('none');
+        spriteProto.visible = false;
+        spriteProto.updateVisible();
+        expect($('.mesh').css('display')).toBe('none');
+      });
+
+      it('should update the mesh display on true', function() {
+        expect($('.mesh').css('display')).toBe('none');
+        spriteProto.visible = true; 
+        spriteProto.updateVisible();
+        expect($('.mesh').css('display')).toBe('inline');
+      });
+
+    });
+
+    describe('talkBubble', function() {
+      it('should update the talkBubble on talkBubble true and visible true', function() {
+        expect($('.bubble-container').css('display')).toBe('none');
+        spriteProto.talkBubbleOn = true; 
+        spriteProto.visible = true; 
+        spriteProto.updateVisible();
+        expect($('.bubble-container').css('display')).toBe('inline-block');
+      });
+
+      it('should update the talkBubble on talkBubble false and visible true', function() {
+        expect($('.bubble-container').css('display')).toBe('none');
+        spriteProto.talkBubbleOn = false; 
+        spriteProto.visible = true; 
+        spriteProto.updateVisible();
+        expect($('.bubble-container').css('display')).toBe('none');
+      });
+
+      it('should update the talkBubble on talkBubble true and visible false', function() {
+        expect($('.bubble-container').css('display')).toBe('none');
+        spriteProto.talkBubbleOn = true; 
+        spriteProto.visible = false; 
+        spriteProto.updateVisible();
+        expect($('.bubble-container').css('display')).toBe('none');
+      });
+    });
+
+    describe('askContainer', function() {
+      it('should update the askInput on askInput true and visible true', function() {
+        expect($('.ask-container').css('display')).toBe('none');
+        spriteProto.askInputOn = true; 
+        spriteProto.visible = true; 
+        spriteProto.updateVisible();
+        expect($('.ask-container').css('display')).toBe('inline-block');
+      });
+
+      it('should update the askInput on askInput false and visible true', function() {
+        expect($('.ask-container').css('display')).toBe('none');
+        spriteProto.askInputOn = false; 
+        spriteProto.visible = true; 
+        spriteProto.updateVisible();
+        expect($('.ask-container').css('display')).toBe('none');
+      });
+
+      it('should update the askInput on askInput true and visible false', function() {
+        expect($('.ask-container').css('display')).toBe('none');
+        spriteProto.askInputOn = true; 
+        spriteProto.visible = false; 
+        spriteProto.updateVisible();
+        expect($('.ask-container').css('display')).toBe('none');
+      });
+    });
+
+  });
+
+  describe('setVisible', function() {
+    var spriteProto;
+    beforeEach(function() {
+      spriteProto = sprite.prototype;
+      spyOn(spriteProto, "updateVisible");
+    });
+
+    it('should set visible to true', function() {
+      expect(spriteProto.visible).toBe(false);
+      spriteProto.setVisible(true);
+      expect(spriteProto.visible).toBe(true);
+      expect(spriteProto.updateVisible).toHaveBeenCalled();
+    });
+
+    it('should set visible to false', function() {
+      spriteProto.visible = true;
+      spriteProto.setVisible(false);
+      expect(spriteProto.visible).toBe(false);
+      expect(spriteProto.updateVisible).toHaveBeenCalled();
+    });
+
+    it('should set take no action on an invalid character', function() {
+      spriteProto.visible = true;
+      spriteProto.setVisible('hello');
+      expect(spriteProto.visible).toBe(true);
+      expect(spriteProto.updateVisible).not.toHaveBeenCalled();
+    });
+
+  });
+});
diff --git a/test/unit/stageSpec.js b/test/unit/stageSpec.js
new file mode 100644
index 0000000..330a451
--- /dev/null
+++ b/test/unit/stageSpec.js
@@ -0,0 +1,51 @@
+/* jasmine specs for Stage.js go here */
+
+describe ('Stage', function() {
+  var stage;
+
+  beforeEach(function() {
+    stage = Stage;
+  });
+
+  describe('Instantization variables', function() {
+    var initStage, lineCanvas;
+    beforeEach(function() {
+      spyOn(Sprite, "call");
+      initStage = new stage(sensingData);
+    });
+
+    describe('Stage Variables', function() {
+      it('should have a z variable', function() {
+        expect(initStage.z).toBe(-2);
+      });
+
+      it('should have a penLayerLoaded variable', function() {
+        expect(initStage.penLayerLoaded).toBe(false);
+      });
+
+      it('should have a lineCanvas element', function() {
+        expect(initStage.lineCanvas).toBeDefined();
+      });
+
+      it('should have a lineCanvas width', function() {
+        expect(initStage.lineCanvas.width).toBe(480);
+      });
+
+      it('should have a lineCanvas height', function() {
+        expect(initStage.lineCanvas.height).toBe(360);
+      });
+
+      it('should have a lineCache variable', function() {
+        expect(initStage.lineCache).toBeDefined();
+      });
+
+      it('should have a isStage variable', function() {
+        expect(initStage.isStage).toBe(true);
+      });
+
+      it('should have called Sprite.call', function() {
+        expect(Sprite.call).toHaveBeenCalled();
+      });
+    });
+  });
+});