diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee
index 92b5036c2..993eed92f 100644
--- a/app/schemas/models/level.coffee
+++ b/app/schemas/models/level.coffee
@@ -245,6 +245,7 @@ _.extend LevelSchema.properties,
   banner: {type: 'string', format: 'image-file', title: 'Banner'}
   goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema
   type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial', 'hero'])
+  terrain: c.terrainString
   showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always'])
 
 c.extendBasicProperties LevelSchema, 'level'
diff --git a/app/schemas/models/thang_type.coffee b/app/schemas/models/thang_type.coffee
index 9ac0319c3..c01c41878 100644
--- a/app/schemas/models/thang_type.coffee
+++ b/app/schemas/models/thang_type.coffee
@@ -106,6 +106,7 @@ _.extend ThangTypeSchema.properties,
     containers: c.object {title: 'Containers', additionalProperties: ContainerObjectSchema}
     animations: c.object {title: 'Animations', additionalProperties: RawAnimationObjectSchema}
   kind: c.shortString {enum: ['Unit', 'Floor', 'Wall', 'Doodad', 'Misc', 'Mark', 'Item'], default: 'Misc', title: 'Kind'}
+  terrains: c.array {title: 'Terrains', description: 'If specified, limits this ThangType to levels with matching terrains.', uniqueItems: true}, c.terrainString
 
   actions: c.object {title: 'Actions', additionalProperties: {$ref: '#/definitions/action'}}
   soundTriggers: c.object {title: 'Sound Triggers', additionalProperties: c.array({}, {$ref: '#/definitions/sound'})},
diff --git a/app/schemas/schemas.coffee b/app/schemas/schemas.coffee
index ea6881729..0eb37689d 100644
--- a/app/schemas/schemas.coffee
+++ b/app/schemas/schemas.coffee
@@ -200,3 +200,5 @@ me.activity = me.object {description: 'Stats on an activity'},
   first: me.date()
   last: me.date()
   count: {type: 'integer', minimum: 0}
+
+me.terrainString = me.shortString {enum: ['Grass', 'Dungeon', 'Indoor'], title: 'Terrain', description: 'Which terrain type this is.'}
diff --git a/app/schemas/subscriptions/editor.coffee b/app/schemas/subscriptions/editor.coffee
index 214404d5c..865f51071 100644
--- a/app/schemas/subscriptions/editor.coffee
+++ b/app/schemas/subscriptions/editor.coffee
@@ -43,8 +43,16 @@ module.exports =
   'level:reload-thang-type': c.object {required: ['thangType']},
     thangType: {type: 'object'}
 
-  'editor:random-terrain-generated': c.object {required: ['thangs']},
+  'editor:random-terrain-generated': c.object {required: ['thangs', 'terrain']},
     thangs: c.array {}, {type: 'object'}
+    terrain: c.terrainString
+
+  'editor:terrain-changed': c.object {required: ['terrain']},
+    terrain:
+      oneOf: [
+        c.terrainString
+        {type: ['null', 'undefined']}
+      ]
 
   'editor:thang-type-kind-changed': c.object {required: ['kind']},
     kind: {type: 'string'}
diff --git a/app/views/editor/level/modals/TerrainRandomizeModal.coffee b/app/views/editor/level/modals/TerrainRandomizeModal.coffee
index 31958e8d0..94a772706 100644
--- a/app/views/editor/level/modals/TerrainRandomizeModal.coffee
+++ b/app/views/editor/level/modals/TerrainRandomizeModal.coffee
@@ -87,6 +87,7 @@ clusters = {
 
 presets = {
   'dungeon': {
+    'terrainName': 'Dungeon'
     'type':'dungeon'
     'borders':'dungeon_wall'
     'borderNoise':0
@@ -128,6 +129,7 @@ presets = {
     }
   }
   'indoor': {
+    'terrainName': 'Indoor'
     'type':'indoor'
     'borders':'indoor_wall'
     'borderNoise':0
@@ -161,6 +163,7 @@ presets = {
     }
   }
   'grassy': {
+    'terrainName': 'Grass'
     'type':'grassy'
     'borders':'trees'
     'borderNoise':1
@@ -223,8 +226,8 @@ thangSizes = {
   'borderSize': {
     'x':4
     'y':4
-  }
-}
+  }}
+
 
 module.exports = class TerrainRandomizeModal extends ModalView
   id: 'terrain-randomize-modal'
@@ -243,7 +246,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
     presetType = target.attr 'data-preset-type'
     presetSize = target.attr 'data-preset-size'
     @randomizeThangs presetType, presetSize
-    Backbone.Mediator.publish 'editor:random-terrain-generated', thangs: @thangs
+    Backbone.Mediator.publish 'editor:random-terrain-generated', thangs: @thangs, terrain: presets[presetType].terrainName
     @hide()
 
   randomizeThangs: (presetName, presetSize) ->
diff --git a/app/views/editor/level/settings/SettingsTabView.coffee b/app/views/editor/level/settings/SettingsTabView.coffee
index 10990c960..fc6e02d91 100644
--- a/app/views/editor/level/settings/SettingsTabView.coffee
+++ b/app/views/editor/level/settings/SettingsTabView.coffee
@@ -13,12 +13,13 @@ module.exports = class SettingsTabView extends CocoView
   # not thangs or scripts or the backend stuff
   editableSettings: [
     'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals',
-    'type', 'showsGuide', 'banner', 'employerDescription'
+    'type', 'terrain', 'showsGuide', 'banner', 'employerDescription'
   ]
 
   subscriptions:
     'editor:level-loaded': 'onLevelLoaded'
     'editor:thangs-edited': 'onThangsEdited'
+    'editor:random-terrain-generated': 'onRandomTerrainGenerated'
 
   constructor: (options) ->
     super options
@@ -47,6 +48,7 @@ module.exports = class SettingsTabView extends CocoView
     @settingsTreema = @$el.find('#settings-treema').treema treemaOptions
     @settingsTreema.build()
     @settingsTreema.open()
+    @lastTerrain = data.terrain
 
   getThangIDs: ->
     (t.id for t in @level.get('thangs') ? [])
@@ -56,11 +58,17 @@ module.exports = class SettingsTabView extends CocoView
     for key in @editableSettings
       continue if @settingsTreema.data[key] is undefined
       @level.set key, @settingsTreema.data[key]
+    if (terrain = @settingsTreema.data.terrain) isnt @lastTerrain
+      @lastTerrain = terrain
+      Backbone.Mediator.publish 'editor:terrain-changed', terrain: terrain
 
   onThangsEdited: (e) ->
     # Update in-place so existing Treema nodes refer to the same array.
     @thangIDs?.splice(0, @thangIDs.length, @getThangIDs()...)
-    
+
+  onRandomTerrainGenerated: (e) ->
+    @settingsTreema.set '/terrain', e.terrain
+
   destroy: ->
     @settingsTreema?.destroy()
     super()
diff --git a/app/views/editor/level/systems/SystemsTabView.coffee b/app/views/editor/level/systems/SystemsTabView.coffee
index eff550260..78809330b 100644
--- a/app/views/editor/level/systems/SystemsTabView.coffee
+++ b/app/views/editor/level/systems/SystemsTabView.coffee
@@ -17,6 +17,7 @@ module.exports = class SystemsTabView extends CocoView
     'editor:edit-level-system': 'editLevelSystem'
     'editor:level-system-editing-ended': 'onLevelSystemEditingEnded'
     'editor:level-loaded': 'onLevelLoaded'
+    'editor:terrain-changed': 'onTerrainChanged'
 
   events:
     'click #add-system-button': 'addLevelSystem'
@@ -103,6 +104,20 @@ module.exports = class SystemsTabView extends CocoView
     @removeSubView @levelSystemEditView
     @levelSystemEditView = null
 
+  onTerrainChanged: (e) ->
+    defaultPathfinding = e.terrain in ['Dungeon', 'Indoor']
+    return unless AI = @systemsTreema.get 'original=528110f30268d018e3000001'
+    return if AI.config?.findsPaths is defaultPathfinding
+    AI.config ?= {}
+    AI.config.findsPaths = defaultPathfinding
+    @systemsTreema.set 'original=528110f30268d018e3000001', AI
+    noty {
+      text: "AI System defaulted pathfinding to #{defaultPathfinding} for terrain #{e.terrain}."
+      layout: 'topCenter'
+      timeout: 5000
+      type: 'information'
+    }
+
   buildDefaultSystems: ->
     [
       {original: '528112c00268d018e3000008', majorVersion: 0}  # Event
@@ -120,6 +135,9 @@ module.exports = class SystemsTabView extends CocoView
       {original: '528111b30268d018e3000004', majorVersion: 0}  # Alliance
       {original: '528114e60268d018e300001a', majorVersion: 0}  # UI
       {original: '528114040268d018e3000011', majorVersion: 0}  # Physics
+      {original: '52ae4f02a4dcd4415200000b', majorVersion: 0}  # Display
+      {original: '52e953e81b2028d102000004', majorVersion: 0}  # Effect
+      {original: '52f1354370fb890000000005', majorVersion: 0}  # Magic
     ]
 
   destroy: ->
diff --git a/app/views/editor/thang/ThangTypeEditView.coffee b/app/views/editor/thang/ThangTypeEditView.coffee
index 186304b2d..6d74534ab 100644
--- a/app/views/editor/thang/ThangTypeEditView.coffee
+++ b/app/views/editor/thang/ThangTypeEditView.coffee
@@ -393,6 +393,8 @@ module.exports = class ThangTypeEditView extends RootView
     if (kind = @treema.data.kind) isnt @lastKind
       @lastKind = kind
       Backbone.Mediator.publish 'editor:thang-type-kind-changed', kind: kind
+      if kind in ['Doodad', 'Floor', 'Wall'] and not @treema.data.terrains
+        @treema.set '/terrains', ['Grass', 'Dungeon', 'Indoor']  # So editors know to set them.
 
   onSelectNode: (e, selected) =>
     selected = selected[0]