diff --git a/app/assets/javascripts/workers/worker_world.js b/app/assets/javascripts/workers/worker_world.js
index 78331cbb8..04d63ea5d 100644
--- a/app/assets/javascripts/workers/worker_world.js
+++ b/app/assets/javascripts/workers/worker_world.js
@@ -298,6 +298,9 @@ self.setupDebugWorldToRunUntilFrame = function (args) {
         }
         Math.random = self.debugWorld.rand.randf;  // so user code is predictable
         Aether.replaceBuiltin("Math", Math);
+        replacedLoDash = _.runInContext(self);
+        for(var key in replacedLoDash)
+          _[key] = replacedLoDash[key];
     }
     self.debugWorld.totalFrames = args.frame; //hack to work around error checking
     self.currentDebugWorldFrame = args.frame;
@@ -353,6 +356,9 @@ self.runWorld = function runWorld(args) {
   }
   Math.random = self.world.rand.randf;  // so user code is predictable
   Aether.replaceBuiltin("Math", Math);
+  replacedLoDash = _.runInContext(self);
+  for(var key in replacedLoDash)
+    _[key] = replacedLoDash[key];
   self.postMessage({type: 'start-load-frames'});
   self.world.loadFrames(self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress);
 };
diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee
index c26838b9e..e9613f21d 100644
--- a/app/lib/Router.coffee
+++ b/app/lib/Router.coffee
@@ -23,7 +23,9 @@ module.exports = class CocoRouter extends Backbone.Router
     # 'account(/:subview)(/*rest)': 'accountView'
 
     # Direct links
+    'test': go('TestView')
     'test/*subpath': go('TestView')
+    'demo': go('DemoView')
     'demo/*subpath': go('DemoView')
     'play/ladder/:levelID': go('play/ladder/ladder_view')
     'play/ladder': go('play/ladder_home')
diff --git a/app/lib/scripts/ScriptManager.coffee b/app/lib/scripts/ScriptManager.coffee
index 0ba6ae9bd..cea2b14ee 100644
--- a/app/lib/scripts/ScriptManager.coffee
+++ b/app/lib/scripts/ScriptManager.coffee
@@ -320,6 +320,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
       if ((noteGroup.script?.skippable) is false) and not options.force
         @noteGroupQueue = @noteGroupQueue[i..]
         @run()
+        @notifyScriptStateChanged()
         return
 
       @processNoteGroup(noteGroup)
@@ -331,6 +332,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
     @noteGroupQueue = []
 
     @resetThings()
+    @notifyScriptStateChanged()
 
   onNoteGroupTimeout: (noteGroup) ->
     return unless noteGroup is @currentNoteGroup
diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee
index 87302f37a..3892d1903 100644
--- a/app/lib/surface/CoordinateDisplay.coffee
+++ b/app/lib/surface/CoordinateDisplay.coffee
@@ -25,9 +25,11 @@ module.exports = class CoordinateDisplay extends createjs.Container
     @mouseEnabled = @mouseChildren = false
     @addChild @background = new createjs.Shape()
     @addChild @label = new createjs.Text('', 'bold 16px Arial', '#FFFFFF')
+    @addChild @pointMarker = new createjs.Shape()
     @label.name = 'Coordinate Display Text'
     @label.shadow = new createjs.Shadow('#000000', 1, 1, 0)
     @background.name = 'Coordinate Display Background'
+    @pointMarker.name = 'Point Marker'
 
   onMouseOver: (e) -> @mouseInBounds = true
   onMouseOut: (e) -> @mouseInBounds = false
@@ -60,26 +62,58 @@ module.exports = class CoordinateDisplay extends createjs.Container
     return unless @label.parent
     @removeChild @label
     @removeChild @background
+    @removeChild @pointMarker
     @uncache()
 
   updateSize: ->
     margin = 3
-    radius = 2.5
-    width = @label.getMeasuredWidth() + 2 * margin
-    height = @label.getMeasuredHeight() + 2 * margin
-    @label.regX = @background.regX = width / 2
-    @label.regY = @background.regY = height / 2
-    @label.regX -= margin
-    @label.regY -= margin
+    contentWidth = @label.getMeasuredWidth() + (2 * margin)
+    contentHeight = @label.getMeasuredHeight() + (2 * margin)
+
+    # Shift all contents up so marker is at pointer (affects container cache position)
+    @label.regY = @background.regY = @pointMarker.regY = contentHeight
+
+    pointMarkerStroke = 2
+    pointMarkerLength = 3
+    contributionsToTotalSize = []
+    contributionsToTotalSize = contributionsToTotalSize.concat @updateCoordinates contentWidth, contentHeight, pointMarkerStroke
+    contributionsToTotalSize = contributionsToTotalSize.concat @updatePointMarker contentHeight, pointMarkerLength, pointMarkerStroke
+
+    totalWidth = contentWidth + contributionsToTotalSize.reduce (a, b) -> a + b
+    totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b
+    [totalWidth, totalHeight]
+
+  updateCoordinates: (contentWidth, contentHeight, initialXYOffset) ->
+    gap = 2
+    labelAndBgMarkerOffset = initialXYOffset * gap
+
+    # Center label horizontally and vertically
+    @label.x = contentWidth / 2 - (@label.getMeasuredWidth() / 2) + labelAndBgMarkerOffset
+    @label.y = contentHeight / 2 - (@label.getMeasuredHeight() / 2) - labelAndBgMarkerOffset
+
     @background.graphics
       .clear()
       .beginFill('rgba(0,0,0,0.4)')
       .beginStroke('rgba(0,0,0,0.6)')
-      .setStrokeStyle(1)
-      .drawRoundRect(0, 0, width, height, radius)
+      .setStrokeStyle(backgroundStroke = 1)
+      .drawRoundRect(labelAndBgMarkerOffset, -labelAndBgMarkerOffset, contentWidth, contentHeight, radius = 2.5)
       .endFill()
       .endStroke()
-    [width, height]
+    contributionsToTotalSize = [labelAndBgMarkerOffset, backgroundStroke]
+
+  updatePointMarker: (contentHeight, length, strokeSize) ->
+    shiftToLineupWithGrid = strokeSize / 2
+    pointMarkerInitialX = strokeSize - shiftToLineupWithGrid
+    pointMarkerInitialY = contentHeight - strokeSize + shiftToLineupWithGrid
+    @pointMarker.graphics
+      .beginStroke('rgb(142, 198, 67')
+      .setStrokeStyle(strokeSize, 'square')
+      .moveTo(pointMarkerInitialX, pointMarkerInitialY)
+      .lineTo(pointMarkerInitialX, pointMarkerInitialY - length)
+      .moveTo(pointMarkerInitialX, pointMarkerInitialY)
+      .lineTo(pointMarkerInitialX + length, pointMarkerInitialY)
+      .endStroke()
+    contributionsToTotalSize = [strokeSize]
 
   show: =>
     return unless @mouseInBounds and @lastPos and not @destroyed
@@ -87,8 +121,9 @@ module.exports = class CoordinateDisplay extends createjs.Container
     [width, height] = @updateSize()
     sup = @camera.worldToSurface @lastPos
     @x = sup.x
-    @y = sup.y - 2.5
+    @y = sup.y
     @addChild @background
     @addChild @label
-    @cache -width / 2, -height / 2, width, height
+    @addChild @pointMarker
+    @cache 0, -height, width, height
     Backbone.Mediator.publish 'surface:coordinates-shown', {}
diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee
index 2c2664a6b..fb30b505a 100644
--- a/app/lib/surface/SpriteBoss.coffee
+++ b/app/lib/surface/SpriteBoss.coffee
@@ -106,7 +106,7 @@ module.exports = class SpriteBoss extends CocoClass
 
   createOpponentWizard: (opponent) ->
     # TODO: colorize name and cloud by team, colorize wizard by user's color config, level-specific wizard spawn points
-    sprite = @createWizardSprite thangID: opponent.id, name: opponent.name
+    sprite = @createWizardSprite thangID: opponent.id, name: opponent.name, codeLanguage: opponent.codeLanguage
     if not opponent.levelSlug or opponent.levelSlug is 'brawlwood'
       sprite.targetPos = if opponent.team is 'ogres' then {x: 52, y: 52} else {x: 28, y: 28}
     else if opponent.levelSlug is 'dungeon-arena'
diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee
index fd745d8ec..f435f8110 100644
--- a/app/lib/surface/Surface.coffee
+++ b/app/lib/surface/Surface.coffee
@@ -608,7 +608,7 @@ module.exports = Surface = class Surface extends CocoClass
       ratio = current % 1
       @world.frames[next].restorePartialState ratio if next > 1
     frame.clearEvents() if parseInt(@currentFrame) is parseInt(@lastFrame)
-    @spriteBoss.updateSounds()
+    @spriteBoss.updateSounds() if parseInt(@currentFrame) isnt parseInt(@lastFrame)
 
   updateState: (frameChanged) ->
     # world state must have been restored in @restoreWorldState
diff --git a/app/lib/surface/WizardSprite.coffee b/app/lib/surface/WizardSprite.coffee
index 9c25c0c7f..5d929147c 100644
--- a/app/lib/surface/WizardSprite.coffee
+++ b/app/lib/surface/WizardSprite.coffee
@@ -54,6 +54,11 @@ module.exports = class WizardSprite extends IndieSprite
     @updateRotation()
     # Don't call general update() because Thang isn't built yet
 
+  setNameLabel: (name) ->
+    if @options.codeLanguage and @options.codeLanguage isnt 'javascript' and not @isSelf
+      name += " (#{@options.codeLanguage})"  # TODO: move on second line, capitalize properly
+    super name
+
   onPlayerStatesChanged: (e) ->
     for playerID, state of e.states
       continue unless playerID is @thang.id
diff --git a/app/lib/utils.coffee b/app/lib/utils.coffee
index 08368a881..663dbe959 100644
--- a/app/lib/utils.coffee
+++ b/app/lib/utils.coffee
@@ -54,6 +54,7 @@ module.exports.i18n = (say, target, language=me.lang(), fallback='en') ->
   generalName = matches[0] if matches
 
   for localeName, locale of say.i18n
+    continue if localeName is '-'
     if target of locale
       result = locale[target]
     else continue
diff --git a/app/lib/world/vector.coffee b/app/lib/world/vector.coffee
index a17e5d077..712d99d64 100644
--- a/app/lib/world/vector.coffee
+++ b/app/lib/world/vector.coffee
@@ -2,13 +2,13 @@
 class Vector
   @className: 'Vector'
   # Class methods for nondestructively operating
-  for name in ['add', 'subtract', 'multiply', 'divide', 'limit', 'normalize']
+  for name in ['add', 'subtract', 'multiply', 'divide', 'limit', 'normalize', 'rotate']
     do (name) ->
       Vector[name] = (a, b, useZ) ->
         a.copy()[name](b, useZ)
 
   isVector: true
-  apiProperties: ['x', 'y', 'z', 'magnitude', 'heading', 'distance', 'dot', 'equals', 'copy', 'distanceSquared']
+  apiProperties: ['x', 'y', 'z', 'magnitude', 'heading', 'distance', 'dot', 'equals', 'copy', 'distanceSquared', 'rotate']
 
   constructor: (@x=0, @y=0, @z=0) ->
 
diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee
index 3e929ef77..eb496133b 100644
--- a/app/lib/world/world.coffee
+++ b/app/lib/world/world.coffee
@@ -207,7 +207,11 @@ module.exports = class World
     map = if kind is 'component' then @componentCodeClassMap else @systemCodeClassMap
     c = map[js]
     return c if c
-    c = map[js] = eval js
+    try
+      c = map[js] = eval js
+    catch err
+      console.error "Couldn't compile #{kind} code:", err, "\n", js
+      c = map[js] = {}
     c.className = name
     c
 
diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee
index 329ce4a32..93541c165 100644
--- a/app/locale/ar.coffee
+++ b/app/locale/ar.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee
index 2c71d71a8..409851289 100644
--- a/app/locale/bg.coffee
+++ b/app/locale/bg.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "български език", englishDescri
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "български език", englishDescri
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee
index 963ab4e9d..ba2af7aa7 100644
--- a/app/locale/ca.coffee
+++ b/app/locale/ca.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee
index 33a31ceac..7e2a61ef2 100644
--- a/app/locale/cs.coffee
+++ b/app/locale/cs.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/da.coffee b/app/locale/da.coffee
index d6fb0dfd3..7d137506e 100644
--- a/app/locale/da.coffee
+++ b/app/locale/da.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee
index 482c2eeab..227969de6 100644
--- a/app/locale/de-AT.coffee
+++ b/app/locale/de-AT.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription:
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription:
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee
index 0e045f99c..dbbd647bf 100644
--- a/app/locale/de-CH.coffee
+++ b/app/locale/de-CH.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee
index 59dbeab1f..b08f8bbd5 100644
--- a/app/locale/de-DE.coffee
+++ b/app/locale/de-DE.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
     revert_models: "Models zurücksetzen."
     fork_title: "Forke neue Version"
     fork_creating: "Erzeuge Fork..."
+#    randomize: "Randomize"
     more: "Mehr"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
     choose_opponent: "Wähle einen Gegner"
+#    select_your_language: "Select your language!"
     tutorial_play: "Spiele Tutorial"
     tutorial_recommended: "Empfohlen, wenn du noch nie zuvor gespielt hast."
     tutorial_skip: "Überspringe Tutorial"
diff --git a/app/locale/de.coffee b/app/locale/de.coffee
index a2f22679c..61ef7caf1 100644
--- a/app/locale/de.coffee
+++ b/app/locale/de.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
     revert_models: "Models zurücksetzen."
     fork_title: "Forke neue Version"
     fork_creating: "Erzeuge Fork..."
+#    randomize: "Randomize"
     more: "Mehr"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
     choose_opponent: "Wähle einen Gegner"
+#    select_your_language: "Select your language!"
     tutorial_play: "Spiele Tutorial"
     tutorial_recommended: "Empfohlen, wenn du noch nie zuvor gespielt hast."
     tutorial_skip: "Überspringe Tutorial"
diff --git a/app/locale/el.coffee b/app/locale/el.coffee
index 4583ce9dc..890553148 100644
--- a/app/locale/el.coffee
+++ b/app/locale/el.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee
index 8f073d7d7..6842729ee 100644
--- a/app/locale/en-AU.coffee
+++ b/app/locale/en-AU.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee
index cea2078f9..18966f32d 100644
--- a/app/locale/en-GB.coffee
+++ b/app/locale/en-GB.coffee
@@ -482,7 +482,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
 #    twitter: "Twitter"
 #    gplus: "Google+"
 
-#  editor:
+  editor:
 #    main_title: "CodeCombat Editors"
 #    main_description: "Build your own levels, campaigns, units and educational content. We provide all the tools you need!"
 #    article_title: "Article Editor"
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+    randomize: "Randomise"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee
index ce19759c6..a1bb56e05 100644
--- a/app/locale/en-US.coffee
+++ b/app/locale/en-US.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index 69373ccfb..c900cbd66 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -499,8 +499,12 @@
     back: "Back"
     revert: "Revert"
     revert_models: "Revert Models"
+    pick_a_terrain: "Pick A Terrain"
+    small: "Small"
+    grassy: "Grassy"
     fork_title: "Fork New Version"
     fork_creating: "Creating Fork..."
+    randomize: "Randomize"
     more: "More"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +805,7 @@
     no_ranked_matches_pre: "No ranked matches for the "
     no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
     choose_opponent: "Choose an Opponent"
+    select_your_language: "Select your language!"
     tutorial_play: "Play Tutorial"
     tutorial_recommended: "Recommended if you've never played before"
     tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee
index 6c8fb4120..b75646620 100644
--- a/app/locale/es-419.coffee
+++ b/app/locale/es-419.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
     no_ranked_matches_pre: "Sin partidas clasificadas para el "
     no_ranked_matches_post: " equipo! Juega en contra de algunos competidores y luego vuelve aquí para ver tu juego clasificado."
     choose_opponent: "Escoge un Oponente"
+#    select_your_language: "Select your language!"
     tutorial_play: "Juega el Tutorial"
     tutorial_recommended: "Recomendado si nunca has jugado antes"
     tutorial_skip: "Saltar Tutorial"
diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee
index a011e016e..c049eb731 100644
--- a/app/locale/es-ES.coffee
+++ b/app/locale/es-ES.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
     revert_models: "Revertir Modelos"
     fork_title: "Bifurcar nueva versión"
     fork_creating: "Creando bifurcación..."
+#    randomize: "Randomize"
     more: "Más"
     wiki: "Wiki"
     live_chat: "Chat en directo"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
     no_ranked_matches_pre: "No hay partidas calificadas para "
     no_ranked_matches_post: " equipo! Juega contra otros competidores y luego vuelve aquí para que tu partida aparezca en la clasificación."
     choose_opponent: "Elige un contrincante"
+#    select_your_language: "Select your language!"
     tutorial_play: "Jugar el Tutorial"
     tutorial_recommended: "Recomendado si no has jugado antes."
     tutorial_skip: "Saltar el Tutorial"
diff --git a/app/locale/es.coffee b/app/locale/es.coffee
index 80a6e5284..5281292f0 100644
--- a/app/locale/es.coffee
+++ b/app/locale/es.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
     tutorial_play: "Jugar Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
     tutorial_skip: "Saltar Tutorial"
diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee
index 5b1ca0e81..6256c0e4e 100644
--- a/app/locale/fa.coffee
+++ b/app/locale/fa.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee
index 83148a058..2d905bec1 100644
--- a/app/locale/fi.coffee
+++ b/app/locale/fi.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee
index af1a2116d..d0e5817ac 100644
--- a/app/locale/fr.coffee
+++ b/app/locale/fr.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
     revert_models: "Annuler les modèles"
     fork_title: "Fork une nouvelle version"
     fork_creating: "Créer un Fork..."
+#    randomize: "Randomize"
     more: "Plus"
     wiki: "Wiki"
     live_chat: "Chat en live"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
     no_ranked_matches_pre: "Pas de match classé pour l'équipe "
     no_ranked_matches_post: "! Affronte d'autres compétiteurs et reviens ici pour classer ta partie."
     choose_opponent: "Choisir un Adversaire"
+#    select_your_language: "Select your language!"
     tutorial_play: "Jouer au Tutoriel"
     tutorial_recommended: "Recommendé si tu n'as jamais joué avant"
     tutorial_skip: "Passer le Tutoriel"
diff --git a/app/locale/he.coffee b/app/locale/he.coffee
index e512e32fc..a0fdeee6b 100644
--- a/app/locale/he.coffee
+++ b/app/locale/he.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew",
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew",
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee
index 57fc1b082..43674f6a6 100644
--- a/app/locale/hi.coffee
+++ b/app/locale/hi.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee
index 84c761e11..1eafea9df 100644
--- a/app/locale/hu.coffee
+++ b/app/locale/hu.coffee
@@ -173,8 +173,8 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
     email_announcements: "Bejelentések"
     email_announcements_description: "Szeretnél levelet kapni a legújabb fejlesztéseinkről?"
     email_notifications: "Értesítések"
-#    email_notifications_summary: "Controls for personalized, automatic email notifications related to your CodeCombat activity."
-    email_any_notes: "Bármely értesítés"
+    email_notifications_summary: "CodeCombat tevékenységedre vonatkozó személyre szóló, automatikus értesítések beállításai."
+    email_any_notes: "Bármely megjegyzés"
     email_any_notes_description: "Minden tevékenységgel kapcsolatos e-mail értesítés letiltása."
     email_recruit_notes: "Álláslehetőségek"
     email_recruit_notes_description: "Ha igazán jól játszol lehet, hogy felveszzük veled a kapcsolatot és megbeszéljük, hogy szerezzünk-e neked egy (jobb) állást."
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/id.coffee b/app/locale/id.coffee
index 6951b4b67..2db554260 100644
--- a/app/locale/id.coffee
+++ b/app/locale/id.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/it.coffee b/app/locale/it.coffee
index 783e6c297..925eb0b28 100644
--- a/app/locale/it.coffee
+++ b/app/locale/it.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t
     no_ranked_matches_pre: "Nessuna partita valutata per "
     no_ranked_matches_post: " squadra! Gioca contro altri avversari e poi torna qui affinchè la tua partita venga valutata."
     choose_opponent: "Scegli un avversario"
+#    select_your_language: "Select your language!"
     tutorial_play: "Gioca il Tutorial"
     tutorial_recommended: "Consigliato se questa è la tua primissima partita"
     tutorial_skip: "Salta il Tutorial"
diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee
index b4a088cb0..60e7e4c2e 100644
--- a/app/locale/ja.coffee
+++ b/app/locale/ja.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee
index bb32495d4..f12d29fa8 100644
--- a/app/locale/ko.coffee
+++ b/app/locale/ko.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     revert_models: "모델 되돌리기"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee
index 6c3df3e2c..4ce34b72f 100644
--- a/app/locale/lt.coffee
+++ b/app/locale/lt.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee
index 5c97c5b2f..5dd010d55 100644
--- a/app/locale/ms.coffee
+++ b/app/locale/ms.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee
index a56bcf571..cec0a46b1 100644
--- a/app/locale/nb.coffee
+++ b/app/locale/nb.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee
index d0fa2550e..3123b8ed5 100644
--- a/app/locale/nl-BE.coffee
+++ b/app/locale/nl-BE.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
     revert_models: "keer wijziging model terug"
     fork_title: "Kloon naar nieuwe versie"
     fork_creating: "Kloon aanmaken..."
+#    randomize: "Randomize"
     more: "Meer"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
     no_ranked_matches_pre: "Geen beoordeelde wedstrijden voor het"
     no_ranked_matches_post: " team! Speel tegen enkele tegenstanders en kom terug hier om uw spel te laten beoordelen."
     choose_opponent: "Kies een tegenstander"
+#    select_your_language: "Select your language!"
     tutorial_play: "Speel de Tutorial"
     tutorial_recommended: "Aanbevolen als je nog niet eerder hebt gespeeld"
     tutorial_skip: "Sla Tutorial over"
diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee
index cffcdbb90..f0844876e 100644
--- a/app/locale/nl-NL.coffee
+++ b/app/locale/nl-NL.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
     revert_models: "keer wijziging model terug"
     fork_title: "Kloon naar nieuwe versie"
     fork_creating: "Kloon aanmaken..."
+#    randomize: "Randomize"
     more: "Meer"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
     no_ranked_matches_pre: "Geen beoordeelde wedstrijden voor het"
     no_ranked_matches_post: " team! Speel tegen enkele tegenstanders en kom terug hier om uw spel te laten beoordelen."
     choose_opponent: "Kies een tegenstander"
+#    select_your_language: "Select your language!"
     tutorial_play: "Speel de Tutorial"
     tutorial_recommended: "Aanbevolen als je nog niet eerder hebt gespeeld"
     tutorial_skip: "Sla Tutorial over"
diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee
index a3dffd22a..2162df73a 100644
--- a/app/locale/nl.coffee
+++ b/app/locale/nl.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
     revert_models: "keer wijziging model terug"
     fork_title: "Kloon naar nieuwe versie"
     fork_creating: "Kloon aanmaken..."
+#    randomize: "Randomize"
     more: "Meer"
     wiki: "Wiki"
     live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
     no_ranked_matches_pre: "Geen beoordeelde wedstrijden voor het"
     no_ranked_matches_post: " team! Speel tegen enkele tegenstanders en kom terug hier om uw spel te laten beoordelen."
     choose_opponent: "Kies een tegenstander"
+#    select_your_language: "Select your language!"
     tutorial_play: "Speel de Tutorial"
     tutorial_recommended: "Aanbevolen als je nog niet eerder hebt gespeeld"
     tutorial_skip: "Sla Tutorial over"
diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee
index 8b208c04c..21016cee4 100644
--- a/app/locale/nn.coffee
+++ b/app/locale/nn.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/no.coffee b/app/locale/no.coffee
index 12fea1777..f4e85c765 100644
--- a/app/locale/no.coffee
+++ b/app/locale/no.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee
index b5b4c1fc1..695ba2937 100644
--- a/app/locale/pl.coffee
+++ b/app/locale/pl.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish
     revert_models: "Przywróć wersję"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish
     no_ranked_matches_pre: "Brak ocenionych pojedynków dla drużyny "
     no_ranked_matches_post: " ! Zagraj przeciwko kilku oponentom i wróc tutaj, aby uzyskać ocenę gry."
     choose_opponent: "Wybierz przeciwnika"
+#    select_your_language: "Select your language!"
     tutorial_play: "Rozegraj samouczek"
     tutorial_recommended: "Zalecane, jeśli wcześniej nie grałeś"
     tutorial_skip: "Pomiń samouczek"
diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee
index 5d2401c91..b678dbdf2 100644
--- a/app/locale/pt-BR.coffee
+++ b/app/locale/pt-BR.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
     revert_models: "Reverter Modelos"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
     more: "Mais"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
     no_ranked_matches_pre: "Sem partidas classificadas para o "
     no_ranked_matches_post: " time! Jogue contra alguns competidores e então volte aqui para ter seu jogo classificado."
     choose_opponent: "Escolha um Oponente"
+#    select_your_language: "Select your language!"
     tutorial_play: "Jogue o Tutorial"
     tutorial_recommended: "Recomendado se você nunca jogou antes"
     tutorial_skip: "Pular Tutorial"
diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 47bdd3772..6a36a4a65 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     revert_models: "Reverter Modelos"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     no_ranked_matches_pre: "Sem jogos classificados pela equipa "
     no_ranked_matches_post: "! Joga contra alguns adversários e volta aqui para veres o teu jogo classificado."
     choose_opponent: "Escolhe um Adversário"
+#    select_your_language: "Select your language!"
     tutorial_play: "Jogar Tutorial"
     tutorial_recommended: "Recomendado se nunca jogaste antes"
     tutorial_skip: "Saltar Tutorial"
diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee
index dd75d506b..ae5e903a3 100644
--- a/app/locale/pt.coffee
+++ b/app/locale/pt.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee
index 2f2ad4c65..fa367f2fd 100644
--- a/app/locale/ro.coffee
+++ b/app/locale/ro.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman
     revert_models: "Resetează Modelele"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman
     no_ranked_matches_pre: "Nici un meci de clasament pentru "
     no_ranked_matches_post: " echipă! Joacă împotriva unor concurenți și revino apoi aici pentr a-ți plasa meciul in clasament."
     choose_opponent: "Alege un adversar"
+#    select_your_language: "Select your language!"
     tutorial_play: "Joacă Tutorial-ul"
     tutorial_recommended: "Recomandat dacă nu ai mai jucat niciodată înainte"
     tutorial_skip: "Sari peste Tutorial"
diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee
index 77fa0be45..2a9a29870 100644
--- a/app/locale/ru.coffee
+++ b/app/locale/ru.coffee
@@ -173,7 +173,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     email_announcements: "Оповещения"
     email_announcements_description: "Получать email-оповещения о последних новостях CodeCombat."
     email_notifications: "Уведомления"
-#    email_notifications_summary: "Controls for personalized, automatic email notifications related to your CodeCombat activity."
+    email_notifications_summary: "Настройки автоматических email-уведомлений, основанных на вашей активности на CodeCombat."
     email_any_notes: "Все уведомления"
     email_any_notes_description: "Отключите, чтобы больше не получать извещения."
     email_recruit_notes: "Возможности для работы"
@@ -399,8 +399,8 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     editor_config_keybindings_label: "Сочетания клавиш"
     editor_config_keybindings_default: "По умолчанию (Ace)"
     editor_config_keybindings_description: "Добавляет дополнительные сочетания, известные из популярных редакторов."
-#    editor_config_livecompletion_label: "Live Autocompletion"
-#    editor_config_livecompletion_description: "Displays autocomplete suggestions while typing."
+    editor_config_livecompletion_label: "Автозаполнение"
+    editor_config_livecompletion_description: "Отображение вариантов автозаполнения во время печати."
     editor_config_invisibles_label: "Показывать непечатные символы"
     editor_config_invisibles_description: "Отображение непечатных символов, таких как пробелы или табуляции."
     editor_config_indentguides_label: "Показывать направляющие отступов"
@@ -451,8 +451,8 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     enter: "Enter"
     escape: "Escape"
     cast_spell: "Произнести текущее заклинание."
-#    continue_script: "Continue past current script."
-#    skip_scripts: "Skip past all skippable scripts."
+    continue_script: "Продолжить текущий скрипт."
+    skip_scripts: "Пропустить все возможные скрипты."
     toggle_playback: "Переключить проигрывание/паузу."
     scrub_playback: "Перемотка назад и вперед во времени."
 #    single_scrub_playback: "Scrub back and forward through time by a single frame."
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     revert_models: "Откатить Модели"
     fork_title: "Форк новой версии"
     fork_creating: "Создание форка..."
+#    randomize: "Randomize"
     more: "Ещё"
     wiki: "Вики"
     live_chat: "Онлайн-чат"
@@ -535,10 +536,10 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     new_thang_title: "Создать новый тип объектов"
     new_level_title: "Создать новый уровень"
     new_article_title_login: "Войти, чтобы создать новую статью"
-#    new_thang_title_login: "Log In to Create a New Thang Type"
-    new_level_title_login: "Войти чтобы создать новый уровень"
-#    new_achievement_title: "Create a New Achievement"
-#    new_achievement_title_login: "Log In to Create a New Achievement"
+    new_thang_title_login: "Войти, чтобы создать новый тип объектов"
+    new_level_title_login: "Войти, чтобы создать новый уровень"
+    new_achievement_title: "Создать новое достижение"
+    new_achievement_title_login: "Войти, чтобы создать новое достижение"
     article_search_title: "Искать статьи"
     thang_search_title: "Искать типы объектов"
     level_search_title: "Искать уровни"
@@ -795,12 +796,13 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     rank_submitted: "Отправлено для оценки"
     rank_failed: "Сбой в оценке"
     rank_being_ranked: "Игра оценивается"
-#    rank_last_submitted: "submitted "
-#    help_simulate: "Help simulate games?"
+    rank_last_submitted: "отправлено "
+    help_simulate: "Нужна помощь в симуляции игр?"
     code_being_simulated: "Ваш новый код участвует в симуляции других игроков для оценки. Обновление будет при поступлении новых матчей."
     no_ranked_matches_pre: "Нет оценённых матчей для команды"
     no_ranked_matches_post: "! Сыграйте против нескольких противников и возвращайтесь сюда для оценки вашей игры."
     choose_opponent: "Выберите противника"
+#    select_your_language: "Select your language!"
     tutorial_play: "Пройти обучение"
     tutorial_recommended: "Рекомендуется, если вы раньше никогда не играли"
     tutorial_skip: "Пропустить обучение"
@@ -809,19 +811,19 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     simple_ai: "Простой ИИ"
     warmup: "Разминка"
     vs: "против"
-#    friends_playing: "Friends Playing"
-#    log_in_for_friends: "Log in to play with your friends!"
-#    social_connect_blurb: "Connect and play against your friends!"
+    friends_playing: "Друзья в игре"
+    log_in_for_friends: "Войти, чтобы поиграть с друзьями!"
+    social_connect_blurb: "Свяжите учетную запись и  играйте против друзей!"
     invite_friends_to_battle: "Пригласить друзей присоединиться к вам в сражении!"
     fight: "В бой!"
-#    watch_victory: "Watch your victory"
-#    defeat_the: "Defeat the"
-#    tournament_ends: "Tournament ends"
-#    tournament_ended: "Tournament ended"
-#    tournament_rules: "Tournament Rules"
-#    tournament_blurb: "Write code, collect gold, build armies, crush foes, win prizes, and upgrade your career in our $40,000 Greed tournament! Check out the details"
-#    tournament_blurb_blog: "on our blog"
-#    rules: "Rules"
+    watch_victory: "Наблюдать за победой"
+    defeat_the: "Победить"
+    tournament_ends: "Турнир заканчивается"
+    tournament_ended: "Турнир закончился"
+    tournament_rules: "Правила турнира"
+    tournament_blurb: "Пишите код, собирайте золото, стройте армию, крушите противников, получайте призы и улучшайте вашу карьеру в нашем \"$40,000 турнире жадности\"! Узнайте больше"
+    tournament_blurb_blog: "в нашем блоге"
+    rules: "Правила"
     winners: "Победители"
 
 #  ladder_prizes:
diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee
index d2db15a1a..bee1b7edf 100644
--- a/app/locale/sk.coffee
+++ b/app/locale/sk.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee
index 4323e23c1..e75b5df8f 100644
--- a/app/locale/sl.coffee
+++ b/app/locale/sl.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee
index 801791e04..6ea2af629 100644
--- a/app/locale/sr.coffee
+++ b/app/locale/sr.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee
index 30fcc2758..49ed0652c 100644
--- a/app/locale/sv.coffee
+++ b/app/locale/sv.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr
     revert_models: "Återställ modeller"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr
     no_ranked_matches_pre: "Inga rankade matcher för "
     no_ranked_matches_post: " laget! Spela mot några motståndare och kom sedan tillbaka it för att få din match rankad."
     choose_opponent: "Välj en motståndare"
+#    select_your_language: "Select your language!"
     tutorial_play: "Spela tutorial"
     tutorial_recommended: "Rekommenderas om du aldrig har spelat tidigare"
     tutorial_skip: "Hoppa över tutorial"
diff --git a/app/locale/th.coffee b/app/locale/th.coffee
index f78ae1e8b..d97529f7b 100644
--- a/app/locale/th.coffee
+++ b/app/locale/th.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee
index fe40f5120..fed1c455a 100644
--- a/app/locale/tr.coffee
+++ b/app/locale/tr.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
     revert_models: "Önceki Modeller"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee
index 8b222c5e5..51d3d34f0 100644
--- a/app/locale/uk.coffee
+++ b/app/locale/uk.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "українська мова", englishDesc
     revert_models: "Моделі повернення"
     fork_title: "Нова версія Форк"
     fork_creating: "Створення Форк..."
+#    randomize: "Randomize"
     more: "Більше"
     wiki: "Wiki"
     live_chat: "Online чат"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "українська мова", englishDesc
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee
index 814c472da..f00732c1b 100644
--- a/app/locale/ur.coffee
+++ b/app/locale/ur.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu",
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu",
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee
index c2489165f..8d6ece181 100644
--- a/app/locale/vi.coffee
+++ b/app/locale/vi.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee
index 611fdba2e..e2436529f 100644
--- a/app/locale/zh-HANS.coffee
+++ b/app/locale/zh-HANS.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
     revert_models: "还原模式"
     fork_title: "派生新版本"
     fork_creating: "正在执行派生..."
+#    randomize: "Randomize"
     more: "更多"
     wiki: "维基"
     live_chat: "在线聊天"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
     choose_opponent: "选择一个对手"
+#    select_your_language: "Select your language!"
     tutorial_play: "玩教程"
     tutorial_recommended: "如果你从未玩过的话,推荐先玩下教程"
     tutorial_skip: "跳过教材"
diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee
index 3c0785dfe..e936fd9a3 100644
--- a/app/locale/zh-HANT.coffee
+++ b/app/locale/zh-HANT.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee
index 91a2eb0d1..4e063c0f6 100644
--- a/app/locale/zh-WUU-HANS.coffee
+++ b/app/locale/zh-WUU-HANS.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee
index 368667c74..2ef6d05f0 100644
--- a/app/locale/zh-WUU-HANT.coffee
+++ b/app/locale/zh-WUU-HANT.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio
     revert_models: "還原模式"
     fork_title: "派生新版本"
     fork_creating: "徠搭執行派生..."
+#    randomize: "Randomize"
     more: "無數"
     wiki: "維基"
     live_chat: "上線白嗒"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
     choose_opponent: "揀一個對手"
+#    select_your_language: "Select your language!"
     tutorial_play: "攪教程"
     tutorial_recommended: "假使爾從來朆攪過個話,建議爾先畀教程攪攪相"
     tutorial_skip: "跳過教程"
diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee
index b9c9d40fb..f7f8d98a0 100644
--- a/app/locale/zh.coffee
+++ b/app/locale/zh.coffee
@@ -501,6 +501,7 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra
 #    revert_models: "Revert Models"
 #    fork_title: "Fork New Version"
 #    fork_creating: "Creating Fork..."
+#    randomize: "Randomize"
 #    more: "More"
 #    wiki: "Wiki"
 #    live_chat: "Live Chat"
@@ -801,6 +802,7 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra
 #    no_ranked_matches_pre: "No ranked matches for the "
 #    no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
 #    choose_opponent: "Choose an Opponent"
+#    select_your_language: "Select your language!"
 #    tutorial_play: "Play Tutorial"
 #    tutorial_recommended: "Recommended if you've never played before"
 #    tutorial_skip: "Skip Tutorial"
diff --git a/app/models/Level.coffee b/app/models/Level.coffee
index 6ae47f25e..f28bb9b00 100644
--- a/app/models/Level.coffee
+++ b/app/models/Level.coffee
@@ -30,7 +30,7 @@ module.exports = class Level extends CocoModel
     visit = (system) ->
       return if system.original of originalsSeen
       systemModel = _.find systemModels, {original: system.original}
-      console.error 'Couldn\'t find model for original', system.original, 'from', systemModels unless systemModel
+      return console.error 'Couldn\'t find model for original', system.original, 'from', systemModels unless systemModel
       for d in systemModel.dependencies or []
         system2 = _.find levelSystems, {original: d.original}
         visit system2
@@ -61,7 +61,7 @@ module.exports = class Level extends CocoModel
           for d in lc.dependencies or []
             c2 = _.find thang.components, {original: d.original}
             console.error thang.id, 'couldn\'t find dependent Component', d.original, 'from', lc.name unless c2
-            visit c2
+            visit c2 if c2
           if lc.name is 'Collides'
             allied = _.find levelComponents, {name: 'Allied'}
             if allied
diff --git a/app/models/User.coffee b/app/models/User.coffee
index cd6fa013b..b1417e08e 100644
--- a/app/models/User.coffee
+++ b/app/models/User.coffee
@@ -7,6 +7,7 @@ module.exports = class User extends CocoModel
   @className: 'User'
   @schema: require 'schemas/models/user'
   urlRoot: '/db/user'
+  notyErrors: false
 
   defaults:
     points: 0
diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee
index a4e655ded..f4f629914 100644
--- a/app/schemas/models/level_session.coffee
+++ b/app/schemas/models/level_session.coffee
@@ -239,6 +239,9 @@ _.extend LevelSessionSchema.properties,
                     title: 'Opponent Rank'
                     description: 'The opponent\'s ranking in a given match'
                     type: 'number'
+              codeLanguage:
+                type: 'string'
+                description: 'What submittedCodeLanguage the opponent used during the match'
 
 c.extendBasicProperties LevelSessionSchema, 'level.session'
 c.extendPermissionsProperties LevelSessionSchema, 'level.session'
diff --git a/app/schemas/subscriptions/misc.coffee b/app/schemas/subscriptions/misc.coffee
index 87ff86cac..439464851 100644
--- a/app/schemas/subscriptions/misc.coffee
+++ b/app/schemas/subscriptions/misc.coffee
@@ -9,6 +9,9 @@ module.exports =
   'note-group-ended':
     {} # TODO schema
 
+  'modal-opened':
+    {} # TODO schema
+
   'modal-closed':
     {} # TODO schema
 
diff --git a/app/schemas/subscriptions/play.coffee b/app/schemas/subscriptions/play.coffee
index cfb9cffd4..4576450de 100644
--- a/app/schemas/subscriptions/play.coffee
+++ b/app/schemas/subscriptions/play.coffee
@@ -32,9 +32,6 @@ module.exports =
   'level-set-grid':
     {} # TODO schema
 
-  'tome:cast-spell':
-    {} # TODO schema
-
   'level:restarted':
     {} # TODO schema
 
diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee
index f19203d0a..42af94472 100644
--- a/app/schemas/subscriptions/tome.coffee
+++ b/app/schemas/subscriptions/tome.coffee
@@ -1,74 +1,217 @@
 module.exports =
-  'tome:cast-spell':
-    {} # TODO schema
+  "tome:cast-spell":
+    title: "Cast Spell"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when a spell is cast"
+    type: ["object", "undefined"]
+    properties:
+      spell:
+        type: "object"
+      thang:
+        type: "object"
+      preload:
+        type: "boolean"
+    required: []
+    additionalProperties: false
 
   # TODO do we really need both 'cast-spell' and 'cast-spells'?
-  'tome:cast-spells':
-    {} # TODO schema
+  "tome:cast-spells":
+    title: "Cast Spells"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when spells are cast"
+    type: ["object", "undefined"]
+    properties:
+      spells:
+        type: "object"
+      preload:
+        type: "boolean"
+    required: []
+    additionalProperties: false
 
-  'tome:manual-cast':
-    {} # TODO schema
+  "tome:manual-cast":
+    title: "Manually Cast Spells"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you wish to manually recast all spells"
+    type: "object"
+    properties: {}
+    required: []
+    additionalProperties: false
 
-  'tome:spell-created':
-    {} # TODO schema
+  "tome:spell-created":
+    title: "Spell Created"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published after a new spell has been created"
+    type: "object"
+    properties:
+      "spell": "object"
+    required: ["spell"]
+    additionalProperties: false
 
-  'tome:spell-debug-property-hovered':
-    {} # TODO schema
+  "tome:spell-debug-property-hovered":
+    title: "Spell Debug Property Hovered"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you hover over a spell property"
+    type: "object"
+    properties:
+      "property": "string"
+      "owner": "string"
+    required: []
+    additionalProperties: false
 
-  'tome:toggle-spell-list':
-    {} # TODO schema
+  "tome:toggle-spell-list":
+    title: "Toggle Spell List"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you toggle the dropdown for a thang's spells"
+    type: "undefined"
+    additionalProperties: false
 
-  'tome:reload-code':
-    {} # TODO schema
+  "tome:reload-code":
+    title: "Reload Code"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you reset a spell to its original source"
+    type: "object"
+    properties:
+      "spell": "object"
+    required: ["spell"]
+    additionalProperties: false
 
-  'tome:palette-hovered':
-    {} # TODO schema
+  "tome:palette-hovered":
+    title: "Palette Hovered"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you hover over a Thang in the spell palette"
+    type: "object"
+    properties:
+      "thang": "object"
+      "prop": "string"
+      "entry": "object"
+    required: ["thang", "prop", "entry"]
+    additionalProperties: false
 
-  'tome:palette-pin-toggled':
-    {} # TODO schema
+  "tome:palette-pin-toggled":
+    title: "Palette Pin Toggled"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you pin or unpin the spell palette"
+    type: "object"
+    properties:
+      "entry": "object"
+      "pinned": "boolean"
+    required: ["entry", "pinned"]
+    additionalProperties: false
 
-  'tome:palette-clicked':
-    {} # TODO schema
+  "tome:palette-clicked":
+    title: "Palette Clicked"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you click on the spell palette"
+    type: "object"
+    properties:
+      "thang": "object"
+      "prop": "string"
+      "entry": "object"
+    required: ["thang", "prop", "entry"]
+    additionalProperties: false
 
-  'tome:spell-statement-index-updated':
-    {} # TODO schema
+  "tome:spell-statement-index-updated":
+    title: "Spell Statement Index Updated"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when the spell index is updated"
+    type: "object"
+    properties:
+      "statementIndex": "object"
+      "ace": "object"
+    required: ["statementIndex", "ace"]
+    additionalProperties: false
 
   # TODO proposition: refactor 'tome' into spell events
-  'spell-beautify':
-    {} # TODO schema
+  "spell-beautify":
+    title: "Beautify"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you click the \"beautify\" button"
+    type: "object"
+    properties:
+      "spell": "object"
+    required: []
+    additionalProperties: false
 
-  'spell-step-forward':
-    {} # TODO schema
+  "spell-step-forward":
+    title: "Step Forward"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you step forward in time"
+    type: "undefined"
+    additionalProperties: false
 
-  'spell-step-backward':
-    {} # TODO schema
+  "spell-step-backward":
+    title: "Step Backward"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you step backward in time"
+    type: "undefined"
+    additionalProperties: false
 
-  'tome:spell-loaded':
-    {} # TODO schema
+  "tome:spell-loaded":
+    title: "Spell Loaded"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when a spell is loaded"
+    type: "object"
+    properties:
+      "spell": "object"
+    required: ["spell"]
+    additionalProperties: false
 
-  'tome:cast-spell':
-    {} # TODO schema
+  "tome:spell-changed":
+    title: "Spell Changed"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when a spell is changed"
+    type: "object"
+    properties:
+      "spell": "object"
+    required: ["spell"]
+    additionalProperties: false
 
-  'tome:spell-changed':
-    {} # TODO schema
+  "tome:editing-began":
+    title: "Editing Began"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you have begun changing code"
+    type: "undefined"
+    additionalProperties: false
 
-  'tome:editing-ended':
-    {} # TODO schema
+  "tome:editing-ended":
+    title: "Editing Ended"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you have stopped changing code"
+    type: "undefined"
+    additionalProperties: false
 
-  'tome:editing-began':
-    {} # TODO schema
+  "tome:problems-updated":
+    title: "Problems Updated"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when problems have been updated"
+    type: "object"
+    properties:
+      "spell": "object"
+      "problems": "array"
+      "isCast": "boolean"
+    required: ["spell", "problems", "isCast"]
+    additionalProperties: false
 
-  'tome:problems-updated':
-    {} # TODO schema
+  "tome:thang-list-entry-popover-shown":
+    title: "Thang List Entry Popover Shown"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when we show the popover for a thang in the master list"
+    type: "object"
+    properties:
+      "entry": "object"
+    required: ["entry"]
+    additionalProperties: false
 
-  'tome:thang-list-entry-popover-shown':
-    {} # TODO schema
-
-  'tome:spell-shown':
-    {} # TODO schema
-
-  'tome:focus-editor':
-    {} # TODO schema
+  "tome:spell-shown":
+    title: "Spell Shown"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when we show a spell"
+    type: "object"
+    properties:
+      "thang": "object"
+      "spell": "object"
+    required: ["thang", "spell"]
+    additionalProperties: false
 
   'tome:change-language':
     title: 'Tome Change Language'
@@ -93,3 +236,37 @@ module.exports =
       language:
         type: 'string'
     required: ['spell']
+
+  "tome:comment-my-code":
+    title: "Comment My Code"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when we comment out a chunk of your code"
+    type: "undefined"
+    additionalProperties: false
+
+  "tome:change-config":
+    title: "Change Config"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when you change your tome settings"
+    type: "undefined"
+    additionalProperties: false
+
+  "tome:update-snippets":
+    title: "Update Snippets"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published when we need to add Zatanna Snippets"
+    type: "object"
+    properties:
+      "propGroups": "object"
+      "allDocs": "object"
+      "language": "string"
+    required: ["propGroups", "allDocs"]
+    additionalProperties: false
+
+  # TODO proposition: add tome to name
+  "focus-editor":
+    title: "Focus Editor"
+    $schema: "http://json-schema.org/draft-04/schema#"
+    description: "Published whenever we want to give focus back to the editor"
+    type: "undefined"
+    additionalProperties: false
diff --git a/app/styles/bootstrap.scss b/app/styles/bootstrap.scss
deleted file mode 100644
index 457a7ab36..000000000
--- a/app/styles/bootstrap.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "bootstrap/bootstrap";
\ No newline at end of file
diff --git a/app/styles/terrain_randomise.sass b/app/styles/editor/level/modal/terrain_randomize.sass
similarity index 99%
rename from app/styles/terrain_randomise.sass
rename to app/styles/editor/level/modal/terrain_randomize.sass
index e6cf29bec..892d4d52f 100644
--- a/app/styles/terrain_randomise.sass
+++ b/app/styles/editor/level/modal/terrain_randomize.sass
@@ -1,4 +1,4 @@
-#terrain-randomise-modal
+#terrain-randomize-modal
 
   .choose-option
     margin-bottom: 15px
diff --git a/app/styles/modal/wizard_settings.sass b/app/styles/modal/wizard_settings.sass
index 09c4bc10e..7ba94a9c3 100644
--- a/app/styles/modal/wizard_settings.sass
+++ b/app/styles/modal/wizard_settings.sass
@@ -9,9 +9,9 @@
     display: block
     float: none
     background: white
-    
-  .wizard-name-line
+
+  #wizard-settings-name-wrapper
+    padding-left: 0px !important
+
+  .help-block
     text-align: center
-    margin-bottom: 10px
-    label
-      margin-right: 10px
\ No newline at end of file
diff --git a/app/styles/play/ladder/ladder_tab.sass b/app/styles/play/ladder/ladder_tab.sass
index cdc5025aa..c92726c9c 100644
--- a/app/styles/play/ladder/ladder_tab.sass
+++ b/app/styles/play/ladder/ladder_tab.sass
@@ -50,3 +50,9 @@
 
   td
     padding: 1px 2px
+
+  .code-language-cell
+    padding: 0 10px
+    background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
+    background-size: contain
+    height: 19px
diff --git a/app/styles/play/ladder/my_matches_tab.sass b/app/styles/play/ladder/my_matches_tab.sass
index 99e01f997..741a3a534 100644
--- a/app/styles/play/ladder/my_matches_tab.sass
+++ b/app/styles/play/ladder/my_matches_tab.sass
@@ -37,3 +37,9 @@
 
   td
     padding: 1px 2px
+
+  .code-language-cell
+    padding: 0 10px
+    background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
+    background-size: contain
+    height: 19px
diff --git a/app/styles/play/ladder/play_modal.sass b/app/styles/play/ladder/play_modal.sass
index 465052114..3587c557f 100644
--- a/app/styles/play/ladder/play_modal.sass
+++ b/app/styles/play/ladder/play_modal.sass
@@ -95,7 +95,17 @@
     span
       position: relative
       top: 1px
-      
+
+    .code-language
+      position: absolute
+      background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
+      background-size: contain
+      width: 40px
+      height: 40px
+      right: -5px
+      top: -15px
+      display: block
+
   .my-name
     border-right: 15px solid transparent
     left: 0
@@ -145,4 +155,4 @@
     top: 35px
     font-size: 40px
     font-weight: bolder
-    color: black
\ No newline at end of file
+    color: black
diff --git a/app/styles/play/level/tome/spell_list_entry.sass b/app/styles/play/level/tome/spell_list_entry.sass
index 8f8683c41..565330c7c 100644
--- a/app/styles/play/level/tome/spell_list_entry.sass
+++ b/app/styles/play/level/tome/spell_list_entry.sass
@@ -13,13 +13,14 @@
   $childMargin: 2px
   $childSize: $height - 2 * $childMargin
   height: $height
-  width: 80%
-  width: -webkit-calc(100% - 100px)
-  width: calc(100% - 100px)
+  width: 90%
+  width: -webkit-calc(100% - 50px)
+  width: calc(100% - 50px)
   padding: 0px 8px
   border-width: 3px
   border-image: url(/images/level/code_editor_tab_background.png) 4 fill repeat
-  text-align: center
+  white-space: nowrap
+  position: relative
 
   &.read-only
     background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0%,rgba(0,0,0,0.2) 100%), url(/images/level/code_editor_tab_background.png)
@@ -34,6 +35,11 @@
   .spell-list-button, .thang-avatar-wrapper
     float: left
 
+  .spell-tool-buttons
+    position: absolute
+    right: 0px
+    top: 0px
+
   .reload-code
     float: right
     display: none
@@ -66,6 +72,7 @@
 
   code
     margin-top: 7px
+    font-size: 1vw
 
 .spell-list-entry-view:not(.spell-tab)
   cursor: pointer
@@ -110,4 +117,4 @@ html.no-borderimage
     border-width: 0
     border-image: none
     background: transparent url(/images/level/code_editor_tab_background.png) no-repeat
-    background-size: 100% 100%
\ No newline at end of file
+    background-size: 100% 100%
diff --git a/app/templates/community.jade b/app/templates/community.jade
index 755e55cf4..396a5a416 100644
--- a/app/templates/community.jade
+++ b/app/templates/community.jade
@@ -1,7 +1,7 @@
 extends /templates/base
 
 block content
-  
+
   h1(data-i18n="community.main_title") CodeCombat Community
 
   p There are dozens of ways you can get involved with CodeCombat. Check out the resources we've built, decide what sounds the most fun, and we look forward to working with you!
@@ -15,13 +15,13 @@ block content
       p We have built several tools that enable users to get not only edit, but also build new game content!
 
         ul
-          li 
+          li
             a(href="/editor/level", data-i18n="community.level_editor")
             | : fork, edit, or build your own CodeCombat levels. New levels can be kept private or published to the community.
-          li 
+          li
             a(href="/editor/thang", data-i18n="editor.thang_title")
             | : modify or import new art assets for the game using our powerful editor.
-          li 
+          li
             a(href="/editor/article", data-i18n="editor.article_title")
             | : edit or create documentation used in CodeCombat levels.
 
@@ -35,51 +35,51 @@ block content
 
         ul
 
-          li We write about our progress and current projects on our 
-            a(href="http://blog.codecombat.com", data-i18n="nav.blog")
+          li We write about our progress and current projects on our
+            a.spl(href="http://blog.codecombat.com", data-i18n="nav.blog")
             | .
-          li Participate in our active user community by checking out our 
-            a(href="http://discourse.codecombat.com", data-i18n="nav.forum") 
+          li Participate in our active user community by checking out our
+            a.spl(href="http://discourse.codecombat.com", data-i18n="nav.forum")
             | .
-          li For regular news about learning to code, games, and education, check out our 
-            a(href="https://www.facebook.com/codecombat", data-i18n="community.facebook") 
+          li For regular news about learning to code, games, and education, check out our
+            a.spl(href="https://www.facebook.com/codecombat", data-i18n="community.facebook")
             | .
-          li For realtime status or to have a quick chat, follow us on 
-            a(href="https://twitter.com/CodeCombat", data-i18n="community.twitter") 
+          li For realtime status or to have a quick chat, follow us on
+            a.spl(href="https://twitter.com/CodeCombat", data-i18n="community.twitter")
             | .
-          li Don't like Facebook? We're on 
-            a(href="https://plus.google.com/115285980638641924488/posts", data-i18n="community.gplus") 
+          li Don't like Facebook? We're on
+            a.spl(href="https://plus.google.com/115285980638641924488/posts", data-i18n="community.gplus")
             | .
-          li You can also find us in our 
-            a(href="http://www.hipchat.com/g3plnOKqa", data-i18n="editor.hipchat_url")
+          li You can also find us in our
+            a.spl(href="http://www.hipchat.com/g3plnOKqa", data-i18n="editor.hipchat_url")
 
     .community_columns
 
       h2 Contribute
 
-      p Put your skills to use helping us teach the world to code. We have a lot of roles you can consider, and if we don't have a role for you, let us know: 
+      p Put your skills to use helping us teach the world to code. We have a lot of roles you can consider, and if we don't have a role for you, let us know:
 
         ul
 
-          li 
-            a(href="/contribute#archmage", data-i18n="classes.archmage_title") 
+          li
+            a(href="/contribute#archmage", data-i18n="classes.archmage_title")
             | : contribute by writing code.
-          li 
-            a(href="/contribute#artisan", data-i18n="classes.artisan_title") 
+          li
+            a(href="/contribute#artisan", data-i18n="classes.artisan_title")
             | : build new game levels.
-          li 
-            a(href="/contribute#adventurer", data-i18n="classes.adventurer_title") 
+          li
+            a(href="/contribute#adventurer", data-i18n="classes.adventurer_title")
             | : test new game levels.
-          li 
-            a(href="/contribute#scribe", data-i18n="classes.scribe_title") 
+          li
+            a(href="/contribute#scribe", data-i18n="classes.scribe_title")
             | : write educational documentation.
-          li 
-            a(href="/contribute#diplomat", data-i18n="classes.diplomat_title") 
+          li
+            a(href="/contribute#diplomat", data-i18n="classes.diplomat_title")
             | : translate site content.
-          li 
-            a(href="/contribute#ambassador", data-i18n="classes.ambassador_title") 
+          li
+            a(href="/contribute#ambassador", data-i18n="classes.ambassador_title")
             | : support our community of educators and coders.
 
         | Check out the
-        a(href="/contribute", data-i18n="nav.contribute") 
+        a.spl(href="/contribute", data-i18n="nav.contribute")
         |  page to find out more about the roles and how you can get started.
diff --git a/app/templates/editor/level/edit.jade b/app/templates/editor/level/edit.jade
index e446f7613..c1f372e29 100644
--- a/app/templates/editor/level/edit.jade
+++ b/app/templates/editor/level/edit.jade
@@ -49,7 +49,7 @@ block header
         
         if level.get('type') === 'ladder'
           li.dropdown
-            a(data-toggle='dropdown')
+            a(data-toggle='dropdown').play-with-team-parent
               span.glyphicon-play.glyphicon
             ul.dropdown-menu
               li.dropdown-header Play As Which Team?
@@ -70,17 +70,17 @@ block header
               a#level-watch-button
                 span.watch
                   span.glyphicon.glyphicon-eye-open
-                  span.spl Watch
+                  span.spl(data-i18n="common.watch") Watch
                 span.unwatch.secret
                   span.glyphicon.glyphicon-eye-close
-                  span.spl Unwatch
+                  span.spl(data-i18n="common.unwatch") Unwatch
                   
             li(class=anonymous ? "disabled": "")
               a(data-i18n="common.fork")#fork-level-start-button Fork
             li(class=anonymous ? "disabled": "")
               a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert
             li(class=anonymous ? "disabled": "")
-              a(data-toggle="coco-modal", data-target="modal/terrain_randomise", data-i18n="editor.randomise")#randomise-button Randomise
+              a(data-toggle="coco-modal", data-target="editor/level/modal/terrain_randomize", data-i18n="editor.randomize")#randomize-button Randomize
             li(class=anonymous ? "disabled": "")
               a(data-i18n="editor.pop_i18n")#pop-level-i18n-button Populate i18n
             li.divider
diff --git a/app/templates/modal/terrain_randomise.jade b/app/templates/editor/level/modal/terrain_randomize.jade
similarity index 78%
rename from app/templates/modal/terrain_randomise.jade
rename to app/templates/editor/level/modal/terrain_randomize.jade
index 9ac509c68..8ea39185e 100644
--- a/app/templates/modal/terrain_randomise.jade
+++ b/app/templates/editor/level/modal/terrain_randomize.jade
@@ -8,8 +8,8 @@ block modal-body-content
     a(href="#")
         div.choose-option(data-preset-type="grassy", data-preset-size="small")
           div.preset-size.name-label
-            span(data-i18n="ladder.small") Small
+            span(data-i18n="editor.small") Small
           div.preset-name
-            span(data-i18n="ladder.grassy") Grassy
+            span(data-i18n="editor.grassy") Grassy
     //- for model in models
 block modal-footer
diff --git a/app/templates/modal/wizard_settings.jade b/app/templates/modal/wizard_settings.jade
index ea22506ec..5d7d91a6b 100644
--- a/app/templates/modal/wizard_settings.jade
+++ b/app/templates/modal/wizard_settings.jade
@@ -4,10 +4,13 @@ block modal-header-content
   h3(data-i18n="wizard_settings.title2") Customize Your Character
 
 block modal-body-content
-  div.wizard-name-line.form-group
-    label.control-label(for="name")
-      | Your Wizardly Name:
-    input#wizard-settings-name(name="name", type="text", value="#{me.get('name')||''}")
+  form.form-horizontal
+    div.form-group
+      .row
+        label.control-label.col-sm-6(for="name")
+          | Your Wizardly Name:
+        #wizard-settings-name-wrapper.col-sm-4
+          input#wizard-settings-name.form-control.input-sm(name="name", type="text", value="#{me.get('name')||''}")
 
   #wizard-settings-view
 
diff --git a/app/templates/play/ladder/ladder_tab.jade b/app/templates/play/ladder/ladder_tab.jade
index 9a5cf746a..4d682243a 100644
--- a/app/templates/play/ladder/ladder_tab.jade
+++ b/app/templates/play/ladder/ladder_tab.jade
@@ -4,13 +4,13 @@ div#columns.row
       div(id="histogram-display-#{team.name}", class="histogram-display",data-team-name=team.name)
       table.table.table-bordered.table-condensed.table-hover
         tr
-          th
+          th(colspan=2)
           th(colspan=3, style="color: #{team.primaryColor}")
             span= team.name
             span  
             span(data-i18n="ladder.leaderboard") Leaderboard
         tr
-          th
+          th(colspan=2)
           th(data-i18n="general.score") Score
           th(data-i18n="general.name").name-col-cell Name
           th
@@ -21,6 +21,7 @@ div#columns.row
         for session, rank in topSessions
           - var myRow = session.get('creator') == me.id
           tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
+            td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)")
             td.rank-cell= rank + 1
             td.score-cell= Math.round(session.get('totalScore') * 100)
             td.name-col-cell= session.get('creatorName') || "Anonymous"
@@ -34,6 +35,7 @@ div#columns.row
           for session in team.leaderboard.nearbySessions()
             - var myRow = session.get('creator') == me.id
             tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
+              td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)")
               td.rank-cell= session.rank
               td.score-cell= Math.round(session.get('totalScore') * 100)
               td.name-col-cell= session.get('creatorName') || "Anonymous"
diff --git a/app/templates/play/ladder/my_matches_tab.jade b/app/templates/play/ladder/my_matches_tab.jade
index 4d91d0757..a08f6651b 100644
--- a/app/templates/play/ladder/my_matches_tab.jade
+++ b/app/templates/play/ladder/my_matches_tab.jade
@@ -4,7 +4,7 @@ div#columns.row
       table.table.table-bordered.table-condensed
 
         tr
-          th(colspan=4, style="color: #{team.primaryColor}")
+          th(colspan=5, style="color: #{team.primaryColor}")
             span(data-i18n="ladder.summary_your") Your 
             |#{team.name}
             |  
@@ -16,16 +16,17 @@ div#columns.row
 
         if team.session
           tr
-            th(colspan=4)
+            th(colspan=5)
               .ladder-submission-view(data-session-id=team.session.id)
 
         if team.scoreHistory
           tr
-            th(colspan=4, style="color: #{team.primaryColor}")
+            th(colspan=5, style="color: #{team.primaryColor}")
               div(class="score-chart-wrapper", data-team-name=team.name, id="score-chart-#{team.name}")
 
         tr
           th(data-i18n="general.result") Result
+          th
           th(data-i18n="general.opponent") Opponent
           th(data-i18n="general.when") When
           th
@@ -38,6 +39,7 @@ div#columns.row
                 span(data-i18n="general.loss").loss Loss
               if match.state === 'tie'
                 span(data-i18n="general.tie").tie Tie
+            td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + match.codeLanguage +  ".png)")
             td.name-cell= match.opponentName || "Anonymous"
             td.time-cell= match.when
             td.battle-cell
diff --git a/app/templates/play/ladder/play_modal.jade b/app/templates/play/ladder/play_modal.jade
index c3a0eb074..841203b2f 100644
--- a/app/templates/play/ladder/play_modal.jade
+++ b/app/templates/play/ladder/play_modal.jade
@@ -13,13 +13,16 @@ block modal-body-content
     span.btn.btn-primary.btn-block.btn-lg#skip-tutorial-button(data-i18n="ladder.tutorial_skip") Skip Tutorial
 
   div#normal-view
-  
     if tutorialLevelExists
       p.tutorial-suggestion
         strong(data-i18n="ladder.tutorial_not_sure") Not sure what's going on?
         |  
         a(href="/play/level/#{levelID}-tutorial", data-i18n="ladder.tutorial_play_first") Play the tutorial first.
-  
+    h4.language-selection(data-i18n="ladder.select_your_language") Select your language!
+    .form-group.select-group
+      select#tome-language(name="language")
+        for option in languages
+          option(value=option.id selected=(language === option.id))= option.name
     a(href="/play/level/#{levelID}?team=#{teamID}")
       div.play-option
         img(src=myPortrait).my-icon.only-one
@@ -30,6 +33,7 @@ block modal-body-content
           span= myName
         div.opponent-name.name-label
           span(data-i18n="ladder.simple_ai") Simple AI
+          //span.code-language(style="background-image: url(/images/pages/home/language_logo_javascript.png)")
         div.difficulty
           span(data-i18n="ladder.warmup") Warmup
         div(data-i18n="ladder.vs").vs VS
@@ -45,6 +49,8 @@ block modal-body-content
             span= myName
           div.opponent-name.name-label
             span= challengers.easy.opponentName
+            if challengers.easy.codeLanguage
+              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.easy.codeLanguage + ".png)")
           div.difficulty
             span(data-i18n="general.easy") Easy
           div(data-i18n="ladder.vs").vs VS
@@ -60,6 +66,8 @@ block modal-body-content
             span= myName
           div.opponent-name.name-label
             span= challengers.medium.opponentName
+            if challengers.medium.codeLanguage
+              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.medium.codeLanguage + ".png)")
           div.difficulty
             span(data-i18n="general.medium") Medium
           div(data-i18n="ladder.vs").vs VS
@@ -75,6 +83,8 @@ block modal-body-content
             span= myName
           div.opponent-name.name-label
             span= challengers.hard.opponentName
+            if challengers.hard.codeLanguage
+              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.hard.codeLanguage + ".png)")
           div.difficulty
             span(data-i18n="general.hard") Hard
           div(data-i18n="ladder.vs").vs VS
diff --git a/app/templates/play/level/tome/spell_list_tab_entry.jade b/app/templates/play/level/tome/spell_list_tab_entry.jade
index 9199b8a48..d896baa5c 100644
--- a/app/templates/play/level/tome/spell_list_tab_entry.jade
+++ b/app/templates/play/level/tome/spell_list_tab_entry.jade
@@ -4,15 +4,15 @@
 
 code #{methodSignature}
 
-.btn.btn-small.fullscreen-code(title="Expand code editor")
-  i.icon-fullscreen
-  i.icon-resize-small
-    
-.btn.btn-small.reload-code(title="Reload original code for " + spell.name)
-  i.icon-repeat
+.spell-tool-buttons
+  .btn.btn-small.fullscreen-code(title="Expand code editor")
+    i.icon-fullscreen
+    i.icon-resize-small
+      
+  .btn.btn-small.reload-code(title="Reload original code for " + spell.name)
+    i.icon-repeat
+  
+  .btn.btn-small.beautify-code(title="Ctrl+Shift+B: Beautify code for " + spell.name)
+    i.icon-magnet
 
-.btn.btn-small.beautify-code(title="Ctrl+Shift+B: Beautify code for " + spell.name)
-  i.icon-magnet
-
-
-.clearfix
\ No newline at end of file
+  .clearfix
\ No newline at end of file
diff --git a/app/treema-ext.coffee b/app/treema-ext.coffee
index c7b6fac65..d5fda7677 100644
--- a/app/treema-ext.coffee
+++ b/app/treema-ext.coffee
@@ -249,9 +249,9 @@ class JavaScriptTreema extends CodeTreema
 class InternationalizationNode extends TreemaNode.nodeMap.object
   findLanguageName: (languageCode) ->
     # to get around mongoose emtpy object bug, there's a prop in the object which needs to be ignored
-    return '' if languageCode is '-' 
+    return '' if languageCode is '-'
     locale[languageCode]?.nativeDescription or "#{languageCode} Not Found"
-    
+
   getChildren: ->
     res = super(arguments...)
     res = (r for r in res when r[0] isnt '-')
@@ -322,7 +322,7 @@ class LatestVersionReferenceNode extends TreemaNode
     return unless term
     @lastTerm = term
     @getSearchResultsEl().empty().append('Searching')
-    @collection = new LatestVersionCollection()
+    @collection = new LatestVersionCollection([], model: @model)
 
     # HACK while search is broken
 #    @collection.url = "#{@url}?term=#{term}&project=true"
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index eb9e879c0..18bc8edf5 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -26,6 +26,7 @@ module.exports = class EditorLevelView extends View
   events:
     'click #play-button': 'onPlayLevel'
     'click .play-with-team-button': 'onPlayLevel'
+    'click .play-with-team-parent': 'onPlayLevelTeamSelect'
     'click #commit-level-start-button': 'startCommittingLevel'
     'click #fork-level-start-button': 'startForkingLevel'
     'click #level-history-button': 'showVersionHistory'
@@ -77,6 +78,12 @@ module.exports = class EditorLevelView extends View
     @listenTo @patchesView, 'accepted-patch', -> location.reload()
     @$el.find('#level-watch-button').find('> span').toggleClass('secret') if @level.watching()
 
+  onPlayLevelTeamSelect: (e) ->
+    if @childWindow and not @childWindow.closed
+      # We already have a child window open, so we don't need to ask for a team; we'll use its existing team.
+      e.stopImmediatePropagation()
+      @onPlayLevel e
+
   onPlayLevel: (e) ->
     team = $(e.target).data('team')
     sendLevel = =>
diff --git a/app/views/modal/terrain_randomise_modal.coffee b/app/views/editor/level/modal/terrain_randomize_modal.coffee
similarity index 65%
rename from app/views/modal/terrain_randomise_modal.coffee
rename to app/views/editor/level/modal/terrain_randomize_modal.coffee
index d737f929f..cf631d54c 100644
--- a/app/views/modal/terrain_randomise_modal.coffee
+++ b/app/views/editor/level/modal/terrain_randomize_modal.coffee
@@ -1,5 +1,5 @@
 ModalView = require 'views/kinds/ModalView'
-template = require 'templates/modal/terrain_randomise'
+template = require 'templates/editor/level/modal/terrain_randomize'
 CocoModel = require 'models/CocoModel'
 
 clusters = {
@@ -66,16 +66,17 @@ sizes = {
   'borderSize': {
     'x':4
     'y':4
+    'thickness':2
   }
 }
 
-module.exports = class TerrainRandomiseModal extends ModalView
-  id: 'terrain-randomise-modal'
+module.exports = class TerrainRandomizeModal extends ModalView
+  id: 'terrain-randomize-modal'
   template: template
   thangs = []
 
   events:
-    'click .choose-option': 'onRandomise'
+    'click .choose-option': 'onRandomize'
 
   onRevertModel: (e) ->
     id = $(e.target).val()
@@ -83,25 +84,25 @@ module.exports = class TerrainRandomiseModal extends ModalView
     $(e.target).closest('tr').remove()
     @reloadOnClose = true
 
-  onRandomise: (e) ->
+  onRandomize: (e) ->
     target = $(e.target)
     presetType = target.attr 'data-preset-type'
     presetSize = target.attr 'data-preset-size'
-    @randomiseThangs presetType, presetSize
-    Backbone.Mediator.publish('randomise:terrain-generated', 
+    @randomizeThangs presetType, presetSize
+    Backbone.Mediator.publish('randomize:terrain-generated', 
       'thangs': @thangs
     )
     @hide()
 
-  randomiseThangs: (presetName, presetSize) ->
+  randomizeThangs: (presetName, presetSize) ->
     preset = presets[presetName]
     presetSize = sizes[presetSize]
     @thangs = []
-    @randomiseFloor preset, presetSize
-    @randomiseBorder preset, presetSize
-    @randomiseDecorations preset, presetSize
+    @randomizeFloor preset, presetSize
+    @randomizeBorder preset, presetSize
+    @randomizeDecorations preset, presetSize
 
-  randomiseFloor: (preset, presetSize) ->
+  randomizeFloor: (preset, presetSize) ->
     for i in _.range(0, presetSize.x, sizes.floorSize.x)
       for j in _.range(0, presetSize.y, sizes.floorSize.y)
         @thangs.push {
@@ -112,40 +113,42 @@ module.exports = class TerrainRandomiseModal extends ModalView
           }
         }
 
-  randomiseBorder: (preset, presetSize) ->
+  randomizeBorder: (preset, presetSize) ->
     for i in _.range(0-sizes.floorSize.x/2+sizes.borderSize.x, presetSize.x-sizes.floorSize.x/2, sizes.borderSize.x)
-      @thangs.push {
-        'id': @getRandomThang(preset.borders)
-        'pos': {
-          'x': i
-          'y': 0-sizes.floorSize.x/2
+      for j in _.range(sizes.borderSize.thickness)
+        @thangs.push {
+          'id': @getRandomThang(preset.borders)
+          'pos': {
+            'x': i + _.random(-sizes.borderSize.x/2, sizes.borderSize.x/2)
+            'y': 0 - sizes.floorSize.x/2 + _.random(-sizes.borderSize.x/2, sizes.borderSize.x/2)
+          }
         }
-      }
-      @thangs.push {
-        'id': @getRandomThang(preset.borders)
-        'pos': {
-          'x': i
-          'y': presetSize.y - sizes.borderSize.y
+        @thangs.push {
+          'id': @getRandomThang(preset.borders)
+          'pos': {
+            'x': i + _.random(-sizes.borderSize.x/2, sizes.borderSize.x/2)
+            'y': presetSize.y - sizes.borderSize.y + _.random(-sizes.borderSize.x/2, sizes.borderSize.x/2)
+          }
         }
-      }
 
     for i in _.range(0-sizes.floorSize.y/2, presetSize.y-sizes.borderSize.y, sizes.borderSize.y)
-      @thangs.push {
-        'id': @getRandomThang(preset.borders)
-        'pos': {
-          'x': 0-sizes.floorSize.x/2+sizes.borderSize.x
-          'y': i
+      for j in _.range(3)
+        @thangs.push {
+          'id': @getRandomThang(preset.borders)
+          'pos': {
+            'x': 0-sizes.floorSize.x/2+sizes.borderSize.x + _.random(-sizes.borderSize.y/2, sizes.borderSize.y/2)
+            'y': i + _.random(-sizes.borderSize.y/2, sizes.borderSize.y/2)
+          }
         }
-      }
-      @thangs.push {
-        'id': @getRandomThang(preset.borders)
-        'pos': {
-          'x': presetSize.x - sizes.borderSize.x - sizes.floorSize.x/2
-          'y': i
+        @thangs.push {
+          'id': @getRandomThang(preset.borders)
+          'pos': {
+            'x': presetSize.x - sizes.borderSize.x - sizes.floorSize.x/2 + _.random(-sizes.borderSize.y/2, sizes.borderSize.y/2)
+            'y': i + _.random(-sizes.borderSize.y/2, sizes.borderSize.y/2)
+          }
         }
-      }
 
-  randomiseDecorations: (preset, presetSize)->
+  randomizeDecorations: (preset, presetSize)->
     for name, decoration of preset.decorations
       for num in _.range(_.random(decoration.num[0], decoration.num[1]))
         center = 
diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee
index e594b00be..a1b92966a 100644
--- a/app/views/editor/level/thangs_tab_view.coffee
+++ b/app/views/editor/level/thangs_tab_view.coffee
@@ -43,7 +43,7 @@ module.exports = class ThangsTabView extends View
     'sprite:mouse-up': 'onSpriteMouseUp'
     'sprite:double-clicked': 'onSpriteDoubleClicked'
     'surface:stage-mouse-up': 'onStageMouseUp'
-    'randomise:terrain-generated': 'onRandomiseTerrain'
+    'randomize:terrain-generated': 'onRandomizeTerrain'
 
   events:
     'click #extant-thangs-filter button': 'onFilterExtantThangs'
@@ -224,10 +224,14 @@ module.exports = class ThangsTabView extends View
     return unless e.thang
     @editThang thangID: e.thang.id
 
-  onRandomiseTerrain: (e) ->
+  onRandomizeTerrain: (e) ->
+    @thangsBatch = []
+    nonRandomThangs = (thang for thang in @thangsTreema.get('') when not /Random/.test thang.id)
+    @thangsTreema.set '', nonRandomThangs
     for thang in e.thangs
       @selectAddThangType thang.id
-      @addThang @addThangType, thang.pos
+      @addThang @addThangType, thang.pos, true
+    @batchInsert()
     @selectAddThangType null
 
   # TODO: figure out a good way to have all Surface clicks and Treema clicks just proxy in one direction, so we can maintain only one way of handling selection and deletion
@@ -397,8 +401,15 @@ module.exports = class ThangsTabView extends View
     id = treema?.data?.id
     @editThang thangID: id if id
 
-  addThang: (thangType, pos) ->
-    thangID = Thang.nextID(thangType.get('name'), @world) until thangID and not @thangsTreema.get "id=#{thangID}"
+  batchInsert: ->
+    @thangsTreema.set '', @thangsTreema.get('').concat(@thangsBatch)
+    @thangsBatch = []
+
+  addThang: (thangType, pos, batchInsert=false) ->
+    if batchInsert
+      thangID = "Random #{thangType.get('name')} #{@thangsBatch.length}"
+    else
+      thangID = Thang.nextID(thangType.get('name'), @world) until thangID and not @thangsTreema.get "id=#{thangID}"
     if @cloneSourceThang
       components = _.cloneDeep @thangsTreema.get "id=#{@cloneSourceThang.id}/components"
       @selectAddThang null
@@ -408,7 +419,10 @@ module.exports = class ThangsTabView extends View
     physical = _.find components, (c) -> c.config?.pos?
     physical.config.pos = x: pos.x, y: pos.y, z: physical.config.pos.z if physical
     thang = thangType: thangType.get('original'), id: thangID, components: components
-    @thangsTreema.insert '', thang
+    if batchInsert
+      @thangsBatch.push thang
+    else
+      @thangsTreema.insert '', thang
 
   editThang: (e) ->
     if e.target  # click event
diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee
index 21b432dd7..264e3539c 100644
--- a/app/views/kinds/CocoView.coffee
+++ b/app/views/kinds/CocoView.coffee
@@ -177,6 +177,7 @@ module.exports = class CocoView extends Backbone.View
     $('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed
     window.currentModal = modalView
     @getRootView().stopListeningToShortcuts(true)
+    Backbone.Mediator.publish 'modal-opened', {}
 
   modalClosed: =>
     visibleModal.willDisappear() if visibleModal
@@ -190,7 +191,7 @@ module.exports = class CocoView extends Backbone.View
       @openModalView(wm)
     else
       @getRootView().listenToShortcuts(true)
-      Backbone.Mediator.publish 'modal-closed'
+      Backbone.Mediator.publish 'modal-closed', {}
 
   # Loading RootViews
 
diff --git a/app/views/play/ladder/my_matches_tab.coffee b/app/views/play/ladder/my_matches_tab.coffee
index 458b3c441..fc82ce441 100644
--- a/app/views/play/ladder/my_matches_tab.coffee
+++ b/app/views/play/ladder/my_matches_tab.coffee
@@ -73,6 +73,7 @@ module.exports = class MyMatchesTabView extends CocoView
         sessionID: opponent.sessionID
         stale: match.date < submitDate
         fresh: fresh
+        codeLanguage: match.codeLanguage
       }
 
     for team in @teams
diff --git a/app/views/play/ladder/play_modal.coffee b/app/views/play/ladder/play_modal.coffee
index e54e79a18..41bf1e22b 100644
--- a/app/views/play/ladder/play_modal.coffee
+++ b/app/views/play/ladder/play_modal.coffee
@@ -15,6 +15,15 @@ module.exports = class LadderPlayModal extends View
 
   events:
     'click #skip-tutorial-button': 'hideTutorialButtons'
+    'change #tome-language': 'updateLanguage'
+
+  defaultAceConfig:
+    language: 'javascript'
+    keyBindings: 'default'
+    invisibles: false
+    indentGuides: false
+    behaviors: false
+    liveCompletion: true
 
   constructor: (options, @level, @session, @team) ->
     super(options)
@@ -23,8 +32,14 @@ module.exports = class LadderPlayModal extends View
     @startLoadingChallengersMaybe()
     @wizardType = ThangType.loadUniversalWizard()
 
-  # PART 1: Load challengers from the db unless some are in the matches
+  updateLanguage: ->
+    aceConfig = _.cloneDeep me.get('aceConfig') ? {}
+    aceConfig = _.defaults aceConfig, @defaultAceConfig
+    aceConfig.language = @$el.find('#tome-language').val()
+    me.set 'aceConfig', aceConfig
+    me.patch()
 
+  # PART 1: Load challengers from the db unless some are in the matches
   startLoadingChallengersMaybe: ->
     matches = @session?.get('matches')
     if matches?.length then @loadNames() else @loadChallengers()
@@ -73,7 +88,14 @@ module.exports = class LadderPlayModal extends View
     ctx.teamID = @team
     ctx.otherTeamID = @otherTeam
     ctx.tutorialLevelExists = @tutorialLevelExists
-
+    ctx.languages = [
+      {id: 'javascript', name: 'JavaScript'}
+      {id: 'coffeescript', name: 'CoffeeScript'}
+      {id: 'python', name: 'Python (Experimental)'}
+      {id: 'clojure', name: 'Clojure (Experimental)'}
+      {id: 'lua', name: 'Lua (Experimental)'}
+      {id: 'io', name: 'Io (Experimental)'}
+    ]
     teamsList = teamDataFromLevel @level
     teams = {}
     teams[team.id] = team for team in teamsList
@@ -154,7 +176,8 @@ module.exports = class LadderPlayModal extends View
     return unless session
     return {
       sessionID: session.id
-      opponentID: session.get('creator')
+      opponentID: session.get 'creator'
+      codeLanguage: session.get 'submittedCodeLanguage'
     }
 
   challengeInfoFromMatches: (matches) ->
@@ -164,6 +187,7 @@ module.exports = class LadderPlayModal extends View
     return {
       sessionID: opponent.sessionID
       opponentID: opponent.userID
+      codeLanguage: opponent.codeLanguage
     }
 
 class ChallengersData
diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee
index 70a93f6b2..c15fe7c6e 100644
--- a/app/views/play/level_view.coffee
+++ b/app/views/play/level_view.coffee
@@ -138,7 +138,13 @@ module.exports = class PlayLevelView extends View
       supermodel: @supermodel
       firstOnly: true
     @openModalView(new DocsModal(options), true)
-    Backbone.Mediator.subscribeOnce 'modal-closed', @onLevelStarted, @
+    onGuideOpened = ->
+      @guideOpenTime = new Date()
+    onGuideClosed = ->
+      application.tracker?.trackTiming new Date() - @guideOpenTime, 'Intro Guide Time', @levelID, @levelID, 100
+      @onLevelStarted()
+    Backbone.Mediator.subscribeOnce 'modal-opened', onGuideOpened, @
+    Backbone.Mediator.subscribeOnce 'modal-closed', onGuideClosed, @
     return true
 
   getRenderData: ->
@@ -281,7 +287,7 @@ module.exports = class PlayLevelView extends View
     @surface.showLevel()
     if @otherSession
       # TODO: colorize name and cloud by team, colorize wizard by user's color config
-      @surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team'), levelSlug: @level.get('slug')
+      @surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team'), levelSlug: @level.get('slug'), codeLanguage: @otherSession.get('submittedCodeLanguage')
     @loadingView?.unveil()
 
   onLoadingViewUnveiled: (e) ->
diff --git a/config.coffee b/config.coffee
index 940a8e688..26c7687ca 100644
--- a/config.coffee
+++ b/config.coffee
@@ -64,7 +64,7 @@ exports.config =
         'stylesheets/app.css': /^(app|vendor|bower_components)/
       order:
         before: [
-          'app/styles/bootstrap.scss'
+          'app/styles/bootstrap/*'
           'vendor/styles/nanoscroller.scss'
         ]
     templates:
diff --git a/headless_client/worker_world.coffee b/headless_client/worker_world.coffee
index c683c4f1d..fadfc9519 100644
--- a/headless_client/worker_world.coffee
+++ b/headless_client/worker_world.coffee
@@ -91,6 +91,8 @@ work = () ->
       return
     Math.random = self.world.rand.randf # so user code is predictable
     Aether.replaceBuiltin('Math', Math)
+    replacedLoDash = _.runInContext(self)
+    _[key] = replacedLoDash[key] for key, val of replacedLoDash
     console.log 'Loading frames.'
 
     self.postMessage type: 'start-load-frames'
diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee
index 0843b0ffc..bcda60e1c 100644
--- a/server/levels/level_handler.coffee
+++ b/server/levels/level_handler.coffee
@@ -155,7 +155,7 @@ LevelHandler = class LevelHandler extends Handler
 
     sortParameters =
       'totalScore': req.query.order
-    selectProperties = ['totalScore', 'creatorName', 'creator']
+    selectProperties = ['totalScore', 'creatorName', 'creator', 'submittedCodeLanguage']
 
     query = Session
       .find(sessionsQueryParameters)
diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee
index b92fe5017..9f68f0cc1 100644
--- a/server/queues/scoring.coffee
+++ b/server/queues/scoring.coffee
@@ -579,6 +579,7 @@ addMatchToSessions = (newScoreObject, callback) ->
     matchObject.opponents[sessionID].totalScore = session.totalScore
     matchObject.opponents[sessionID].metrics = {}
     matchObject.opponents[sessionID].metrics.rank = Number(newScoreObject[sessionID]?.gameRanking ? 0)
+    matchObject.opponents[sessionID].codeLanguage = newScoreObject[sessionID].submittedCodeLanguage
 
   #log.info "Match object computed, result: #{matchObject}"
   #log.info 'Writing match object to database...'
@@ -595,6 +596,7 @@ updateMatchesInSession = (matchObject, sessionID, callback) ->
   opponentsClone = _.omit opponentsClone, sessionID
   opponentsArray = _.toArray opponentsClone
   currentMatchObject.opponents = opponentsArray
+  currentMatchObject.codeLanguage = matchObject.opponents[opponentsArray[0].sessionID].codeLanguage
   LevelSession.findOne {'_id': sessionID}, (err, session) ->
     session = session.toObject()
     currentMatchObject.playtime = session.playtime ? 0
@@ -770,6 +772,7 @@ retrieveOldSessionData = (sessionID, callback) ->
       'meanStrength': session.meanStrength ? 25
       'totalScore': session.totalScore ? (25 - 1.8*(25/3))
       'id': sessionID
+      'submittedCodeLanguage': session.submittedCodeLanguage
     callback err, oldScoreObject
 
 markSessionAsDoneRanking = (sessionID, cb) ->
diff --git a/server_setup.coffee b/server_setup.coffee
index 49789a9a2..bb72554c4 100644
--- a/server_setup.coffee
+++ b/server_setup.coffee
@@ -75,11 +75,17 @@ setupRedirectMiddleware = (app) ->
     nameOrID = req.path.split('/')[3]
     res.redirect 301, "/user/#{nameOrID}/profile"
 
+setupTrailingSlashRemovingMiddleware = (app) ->
+  app.use (req, res, next) ->
+    return res.redirect 301, req.url[...-1] if req.url.length > 1 and req.url.slice(-1) is '/'
+    next()
+
 exports.setupMiddleware = (app) ->
   setupMiddlewareToSendOldBrowserWarningWhenPlayersViewLevelDirectly app
   setupExpressMiddleware app
   setupPassportMiddleware app
   setupOneSecondDelayMiddleware app
+  setupTrailingSlashRemovingMiddleware app
   setupRedirectMiddleware app
 
 ###Routing function implementations###