diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index cb43f4380..2269b9bab 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -203,6 +203,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
     tome_select_a_thang: "Select Someone for "
     tome_available_spells: "Available Spells"
     hud_continue: "Continue (press shift-space)"
+    spell_saved: "Spell Saved"
 
   admin:
     av_title: "Admin Views"
diff --git a/app/styles/play/level/tome/spell.sass b/app/styles/play/level/tome/spell.sass
index 13c7baad8..0ff18cf23 100644
--- a/app/styles/play/level/tome/spell.sass
+++ b/app/styles/play/level/tome/spell.sass
@@ -18,7 +18,13 @@
     position: absolute
     top: 0
     height: 100%
-    
+
+  .save-status
+    display: none
+    position: relative
+    padding-top: 2px
+    padding-left: 10px
+
   .firepad
     width: 100%
     height: 100%
diff --git a/app/templates/play/level/tome/spell.jade b/app/templates/play/level/tome/spell.jade
index 17dca17bc..85fcdbda0 100644
--- a/app/templates/play/level/tome/spell.jade
+++ b/app/templates/play/level/tome/spell.jade
@@ -1,3 +1,5 @@
 img(src="/images/level/code_editor_background.png").code-background
     
 div.ace
+
+.save-status(data-i18n="play_level.spell_saved") Spell Saved
diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee
index 313e1b761..33314e2e9 100644
--- a/app/views/play/level/tome/spell_view.coffee
+++ b/app/views/play/level/tome/spell_view.coffee
@@ -21,9 +21,11 @@ module.exports = class SpellView extends View
     'god:user-code-problem': 'onUserCodeProblem'
     'tome:manual-cast': 'onManualCast'
     'tome:reload-code': 'onCodeReload'
+    'tome:spell-changed': 'onSpellChanged'
+    'level:session-will-save': 'onSessionWillSave'
     'modal-closed': 'focus'
     'focus-editor': 'focus'
-    
+
   events:
     'click .ace': -> console.log 'clicked ace', @
 
@@ -316,6 +318,16 @@ module.exports = class SpellView extends View
     #else
     #  console.log "valid but not at end of line; recompile in", @autocastDelay + "ms"
 
+  onSpellChanged: (e) ->
+    @spellHasChanged = true
+
+  onSessionWillSave: (e) ->
+    setTimeout(=>
+      unless @spellHasChanged
+        @$el.find('.save-status').finish().show().fadeOut(2000)
+    , 1000)
+    @spellHasChanged = false
+
   onUserCodeProblem: (e) ->
     return @onInfiniteLoop e if e.problem.id is "runtime_InfiniteLoop"
     return unless e.problem.userInfo.methodName is @spell.name