diff --git a/app/models/User.coffee b/app/models/User.coffee
index 3fec2a995..79c45e4fc 100644
--- a/app/models/User.coffee
+++ b/app/models/User.coffee
@@ -124,6 +124,15 @@ module.exports = class User extends CocoModel
     application.tracker.identify gemPromptGroup: @gemPromptGroup unless me.isAdmin()
     @gemPromptGroup
 
+  getHideLockedLevelsGroup: ->
+    return @hideLockedLevelsGroup if @hideLockedLevelsGroup
+    group = if me.isAdmin() then 0 else me.get('testGroupNumber') % 2
+    @hideLockedLevelsGroup = switch group
+      when 0 then 'show'
+      when 1 then 'hide'
+    application.tracker.identify hideLockedLevelsGroup: @hideLockedLevelsGroup unless me.isAdmin()
+    @hideLockedLevelsGroup
+
 tiersByLevel = [-1, 0, 0.05, 0.14, 0.18, 0.32, 0.41, 0.5, 0.64, 0.82, 0.91, 1.04, 1.22, 1.35, 1.48, 1.65, 1.78, 1.96, 2.1, 2.24, 2.38, 2.55, 2.69, 2.86, 3.03, 3.16, 3.29, 3.42, 3.58, 3.74, 3.89, 4.04, 4.19, 4.32, 4.47, 4.64, 4.79, 4.96,
   5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15
 ]
diff --git a/app/templates/play/world-map-view.jade b/app/templates/play/world-map-view.jade
index a11003fff..1c2a12d06 100644
--- a/app/templates/play/world-map-view.jade
+++ b/app/templates/play/world-map-view.jade
@@ -10,30 +10,32 @@
     if !level.hidden
       - var next = level.id == nextLevel || (!seenNext && levelStatusMap[level.id] != "complete" && !level.locked && !level.disabled && (!level.practice || me.getBranchingGroup() == 'all-practice'));
       - seenNext = seenNext || next;
-      div(style="left: #{level.x}%; bottom: #{level.y}%; background-color: #{level.color}", class="level" + (next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.id] || "", data-level-id=level.id, title=level.name + (level.disabled ? ' (Coming Soon to Adventurers)' : ''))
-        a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, data-level-id=level.id, data-level-path=level.levelPath || 'level', data-level-name=level.name)
-      div(style="left: #{level.x}%; bottom: #{level.y}%", class="level-shadow" + (next ? " next" : "") + " " + levelStatusMap[level.id] || "")
-      .level-info-container(data-level-id=level.id, data-level-path=level.levelPath || 'level', data-level-name=level.name)
-        div(class="level-info " + (levelStatusMap[level.id] || ""))
-          h3= level.name + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : ""))
-          .level-description= level.description
-          if level.disabled
-            p
-              span.spr(data-i18n="play.awaiting_levels_adventurer_prefix") We release five levels per week.
-              a.spr(href="/contribute/adventurer")
-                strong(data-i18n="play.awaiting_levels_adventurer") Sign up as an Adventurer
-              span.spl(data-i18n="play.awaiting_levels_adventurer_suffix") to be the first to play new levels.
-              
-          - var playCount = levelPlayCountMap[level.id]
-          if playCount && playCount.sessions > 20
-            div
-              span.spr #{playCount.sessions}
-              span(data-i18n="play.players") players
-              span.spr , #{Math.round(playCount.playtime / 3600)}
-              span(data-i18n="play.hours_played") hours played
-          .campaign-label(style="color: #{campaign.color}")= campaign.name
-        if isIPadApp && !level.disabled && !level.locked
-          button.btn.btn-success.btn-lg.start-level(data-i18n="common.play") Play
+      //- A/B Test hiding locked levels
+      if !hideLockedLevels || !level.locked
+        div(style="left: #{level.x}%; bottom: #{level.y}%; background-color: #{level.color}", class="level" + (next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.id] || "", data-level-id=level.id, title=level.name + (level.disabled ? ' (Coming Soon to Adventurers)' : ''))
+          a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, data-level-id=level.id, data-level-path=level.levelPath || 'level', data-level-name=level.name)
+        div(style="left: #{level.x}%; bottom: #{level.y}%", class="level-shadow" + (next ? " next" : "") + " " + levelStatusMap[level.id] || "")
+        .level-info-container(data-level-id=level.id, data-level-path=level.levelPath || 'level', data-level-name=level.name)
+          div(class="level-info " + (levelStatusMap[level.id] || ""))
+            h3= level.name + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : ""))
+            .level-description= level.description
+            if level.disabled
+              p
+                span.spr(data-i18n="play.awaiting_levels_adventurer_prefix") We release five levels per week.
+                a.spr(href="/contribute/adventurer")
+                  strong(data-i18n="play.awaiting_levels_adventurer") Sign up as an Adventurer
+                span.spl(data-i18n="play.awaiting_levels_adventurer_suffix") to be the first to play new levels.
+                
+            - var playCount = levelPlayCountMap[level.id]
+            if playCount && playCount.sessions > 20
+              div
+                span.spr #{playCount.sessions}
+                span(data-i18n="play.players") players
+                span.spr , #{Math.round(playCount.playtime / 3600)}
+                span(data-i18n="play.hours_played") hours played
+            .campaign-label(style="color: #{campaign.color}")= campaign.name
+          if isIPadApp && !level.disabled && !level.locked
+            button.btn.btn-success.btn-lg.start-level(data-i18n="common.play") Play
   if mapType === 'dungeon' && forestIsAvailable
     a#forest-link.glyphicon.glyphicon-share-alt.campaign-switch(href="/play/forest", data-i18n="[title]play.campaign_forest")
   if mapType === 'forest'
diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee
index c53acde7e..596236133 100644
--- a/app/views/play/WorldMapView.coffee
+++ b/app/views/play/WorldMapView.coffee
@@ -69,7 +69,9 @@ module.exports = class WorldMapView extends RootView
     @hadEverChosenHero = me.get('heroConfig')?.thangType
     @listenTo me, 'change:purchased', -> @renderSelectors('#gems-count')
     @listenTo me, 'change:spent', -> @renderSelectors('#gems-count')
-    window.tracker?.trackEvent 'Loaded World Map', category: 'World Map', ['Google Analytics']
+    # A/B Test hiding locked levels
+    # window.tracker?.trackEvent 'Loaded World Map', category: 'World Map', ['Google Analytics']
+    window.tracker?.trackEvent 'Loaded World Map', category: 'World Map', hideLockedLevelsGroup: me.getHideLockedLevelsGroup()
 
     # If it's a new player who didn't appear to come from Hour of Code, we register her here without setting the hourOfCode property.
     elapsed = (new Date() - new Date(me.get('dateCreated')))
@@ -135,6 +137,8 @@ module.exports = class WorldMapView extends RootView
     context.mapType = _.string.slugify @terrain
     context.nextLevel = @nextLevel
     context.forestIsAvailable = @startedForestLevel or '541b67f71ccc8eaae19f3c62' in (me.get('earned')?.levels or [])
+    # A/B Test hiding locked levels
+    context.hideLockedLevels = me.getHideLockedLevelsGroup() is 'hide'
     context
 
   afterRender: ->