diff --git a/app/application.coffee b/app/application.coffee
index 9f23e9f91..b4685e643 100644
--- a/app/application.coffee
+++ b/app/application.coffee
@@ -42,7 +42,7 @@ Application = initialize: ->
   @linkedinHandler = new LinkedInHandler()
   preload(COMMON_FILES)
   $.i18n.init {
-    lng: me?.lang() ? 'en'
+    lng: me.get('preferredLanguage', true)
     fallbackLng: 'en'
     resStore: locale
     #debug: true
diff --git a/app/initialize.coffee b/app/initialize.coffee
index a27c1f7a2..c384c196f 100644
--- a/app/initialize.coffee
+++ b/app/initialize.coffee
@@ -67,9 +67,9 @@ setUpDefinitions = ->
 
 setUpMoment = ->
   {me} = require 'lib/auth'
-  moment.lang me.lang(), {}
-  me.on 'change', (me) ->
-    moment.lang me.lang(), {} if me._previousAttributes.preferredLanguage isnt me.get 'preferredLanguage'
+  moment.lang me.get('preferredLanguage', true), {}
+  me.on 'change:preferredLanguage', (me) ->
+    moment.lang me.get('preferredLanguage', true), {}
 
 initializeServices = ->
   services = [
diff --git a/app/lib/utils.coffee b/app/lib/utils.coffee
index 17167422d..5a4e78594 100644
--- a/app/lib/utils.coffee
+++ b/app/lib/utils.coffee
@@ -46,7 +46,7 @@ toHex = (n) ->
   h = '0'+h if h.length is 1
   h
 
-module.exports.i18n = (say, target, language=me.lang(), fallback='en') ->
+module.exports.i18n = (say, target, language=me.get('preferredLanguage', true), fallback='en') ->
   generalResult = null
   fallbackResult = null
   fallforwardResult = null # If a general language isn't available, the first specific one will do
diff --git a/app/models/User.coffee b/app/models/User.coffee
index eebb3d88c..d9af11f11 100644
--- a/app/models/User.coffee
+++ b/app/models/User.coffee
@@ -19,7 +19,6 @@ module.exports = class User extends CocoModel
 
   isAnonymous: -> @get('anonymous', true)
   displayName: -> @get('name', true)
-  lang: -> @get('preferredLanguage', true)
 
   getPhotoURL: (size=80, useJobProfilePhoto=false, useEmployerPageAvatar=false) ->
     photoURL = if useJobProfilePhoto then @get('jobProfile')?.photoURL else null
diff --git a/app/schemas/models/achievement.coffee b/app/schemas/models/achievement.coffee
index 35bd36bba..4f5181f92 100644
--- a/app/schemas/models/achievement.coffee
+++ b/app/schemas/models/achievement.coffee
@@ -38,15 +38,20 @@ c.extendNamedProperties AchievementSchema
 c.extendBasicProperties AchievementSchema, 'achievement'
 c.extendSearchableProperties AchievementSchema
 
+AchievementSchema.default =
+  worth: 10
+  description: 'Probably the coolest you\'ll ever get.'
+  difficulty: 1
+  recalculable: true
+  function: {}
+
 _.extend AchievementSchema.properties,
   query:
     #type:'object'
     $ref: '#/definitions/' + MongoFindQuerySchema.id
   worth: c.float
-    default: 10
   collection: {type: 'string'}
-  description: c.shortString
-    default: 'Probably the coolest you\'ll ever get.'
+  description: c.shortString()
   userField: c.shortString()
   related: c.objectId(description: 'Related entity')
   icon: {type: 'string', format: 'image-file', title: 'Icon', description: 'Image should be a 100x100 transparent png.'}
@@ -55,27 +60,26 @@ _.extend AchievementSchema.properties,
     description: 'For categorizing and display purposes'
   difficulty: c.int
     description: 'The higher the more difficult'
-    default: 1
   proportionalTo:
     type: 'string'
     description: 'For repeatables only. Denotes the field a repeatable achievement needs for its calculations'
   recalculable:
     type: 'boolean'
     description: 'Needs to be set to true before it is elligible for recalculation.'
-    default: true
   function:
     type: 'object'
     description: 'Function that gives total experience for X amount achieved'
     properties:
-      kind: {enum: ['linear', 'logarithmic', 'quadratic'], default: 'linear'}
+      kind: {enum: ['linear', 'logarithmic', 'quadratic'] }
       parameters:
         type: 'object'
+        default: { a: 1, b: 1, c: 1 }
         properties:
-          a: {type: 'number', default: 1}
-          b: {type: 'number', default: 1}
-          c: {type: 'number', default: 1}
+          a: {type: 'number' }
+          b: {type: 'number' }
+          c: {type: 'number' }
         additionalProperties: true
-    default: {kind: 'linear', parameters: a: 1}
+    default: {kind: 'linear', parameters: {}}
     required: ['kind', 'parameters']
     additionalProperties: false
   i18n: c.object
diff --git a/app/schemas/models/earned_achievement.coffee b/app/schemas/models/earned_achievement.coffee
index 12451ceac..04cfe9b91 100644
--- a/app/schemas/models/earned_achievement.coffee
+++ b/app/schemas/models/earned_achievement.coffee
@@ -3,6 +3,9 @@ c = require './../schemas'
 module.exports =
   EarnedAchievementSchema =
     type: 'object'
+    default:
+      previouslyAchievedAmount: 0
+      
     properties:
       user: c.objectId
         links:
@@ -26,5 +29,5 @@ module.exports =
       changed: type: 'date'
       achievedAmount: type: 'number'
       earnedPoints: type: 'number'
-      previouslyAchievedAmount: {type: 'number', default: 0}
+      previouslyAchievedAmount: {type: 'number'}
       notified: type: 'boolean'
diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee
index 2fa229ee1..ae05899c2 100644
--- a/app/schemas/models/level.coffee
+++ b/app/schemas/models/level.coffee
@@ -11,7 +11,7 @@ side = {title: 'Side', description: 'A side.', type: 'string', 'enum': ['left',
 thang = {title: 'Thang', description: 'The name of a Thang.', type: 'string', maxLength: 30, format: 'thang'}
 
 eventPrereqValueTypes = ['boolean', 'integer', 'number', 'null', 'string'] # not 'object' or 'array'
-EventPrereqSchema = c.object {title: 'Event Prerequisite', format: 'event-prereq', description: 'Script requires that the value of some property on the event triggering it to meet some prerequisite.', 'default': {eventProps: []}, required: ['eventProps']},
+EventPrereqSchema = c.object {title: 'Event Prerequisite', format: 'event-prereq', description: 'Script requires that the value of some property on the event triggering it to meet some prerequisite.', required: ['eventProps']},
   eventProps: c.array {'default': ['thang'], format: 'event-value-chain', maxItems: 10, title: 'Event Property', description: 'A chain of keys in the event, like "thang.pos.x" to access event.thang.pos.x.'}, c.shortString(title: 'Property', description: 'A key in the event property key chain.')
   equalTo: c.object {type: eventPrereqValueTypes, title: '==', description: 'Script requires the event\'s property chain value to be equal to this value.'}
   notEqualTo: c.object {type: eventPrereqValueTypes, title: '!=', description: 'Script requires the event\'s property chain value to *not* be equal to this value.'}
@@ -30,7 +30,7 @@ GoalSchema = c.object {title: 'Goal', description: 'A goal that the player can a
   id: c.shortString(title: 'ID', description: 'Unique identifier for this goal, like \"defeat-dragons\".', pattern: '^[a-z0-9-]+$')  # unique somehow?
   worldEndsAfter: {title: 'World Ends After', description: 'When included, ends the world this many seconds after this goal succeeds or fails.', type: 'number', minimum: 0, exclusiveMinimum: true, maximum: 300, default: 3}
   howMany: {title: 'How Many', description: 'When included, require only this many of the listed goal targets instead of all of them.', type: 'integer', minimum: 1}
-  hiddenGoal: {title: 'Hidden', description: 'Hidden goals don\'t show up in the goals area for the player until they\'re failed. (Usually they\'re obvious, like "don\'t die".)', 'type': 'boolean', default: false}
+  hiddenGoal: {title: 'Hidden', description: 'Hidden goals don\'t show up in the goals area for the player until they\'re failed. (Usually they\'re obvious, like "don\'t die".)', 'type': 'boolean' }
   team: c.shortString(title: 'Team', description: 'Name of the team this goal is for, if it is not for all of the playable teams.')
   killThangs: c.array {title: 'Kill Thangs', description: 'A list of Thang IDs the player should kill, or team names.', uniqueItems: true, minItems: 1, 'default': ['ogres']}, thang
   saveThangs: c.array {title: 'Save Thangs', description: 'A list of Thang IDs the player should save, or team names', uniqueItems: true, minItems: 1, 'default': ['humans']}, thang
@@ -70,26 +70,26 @@ ResponseSchema = c.object {title: 'Dialogue Button', description: 'A button to b
   buttonClass: c.shortString(title: 'Button Class', description: 'CSS class that will be added to the button, like "btn-primary".')
   i18n: {type: 'object', format: 'i18n', props: ['text'], description: 'Help translate this button'}
 
-PointSchema = c.object {title: 'Point', description: 'An {x, y} coordinate point.', format: 'point2d', required: ['x', 'y']},
-  x: {title: 'x', description: 'The x coordinate.', type: 'number', 'default': 15}
-  y: {title: 'y', description: 'The y coordinate.', type: 'number', 'default': 20}
+PointSchema = c.object {title: 'Point', description: 'An {x, y} coordinate point.', format: 'point2d', default: { x:15, y:20 }},
+  x: {title: 'x', description: 'The x coordinate.', type: 'number'}
+  y: {title: 'y', description: 'The y coordinate.', type: 'number'}
 
 SpriteCommandSchema = c.object {title: 'Thang Command', description: 'Make a target Thang move or say something, or select/deselect it.', required: ['id'], default: {id: 'Captain Anya'}},
   id: thang
   select: {title: 'Select', description: 'Select or deselect this Thang.', type: 'boolean'}
-  say: c.object {title: 'Say', description: 'Make this Thang say a message.', required: ['text']},
+  say: c.object {title: 'Say', description: 'Make this Thang say a message.', required: ['text'], default: { mood: 'explain' }},
     blurb: c.shortString(title: 'Blurb', description: 'A very short message to display above this Thang\'s head. Plain text.', maxLength: 50)
-    mood: c.shortString(title: 'Mood', description: 'The mood with which the Thang speaks.', 'enum': ['explain', 'debrief', 'congrats', 'attack', 'joke', 'tip', 'alarm'], 'default': 'explain')
+    mood: c.shortString(title: 'Mood', description: 'The mood with which the Thang speaks.', 'enum': ['explain', 'debrief', 'congrats', 'attack', 'joke', 'tip', 'alarm'])
     text: {title: 'Text', description: 'A short message to display in the dialogue area. Markdown okay.', type: 'string', maxLength: 400}
-    sound: c.object {title: 'Sound', description: 'A dialogue sound file to accompany the message.', required: ['mp3', 'ogg']},
+    sound: c.object {title: 'Sound', description: 'A dialogue sound file to accompany the message.', required: ['mp3', 'ogg'] },
       mp3: c.shortString(title: 'MP3', format: 'sound-file')
       ogg: c.shortString(title: 'OGG', format: 'sound-file')
-      preload: {title: 'Preload', description: 'Whether to load this sound file before the level can begin (typically for the first dialogue of a level).', type: 'boolean', 'default': false}
+      preload: {title: 'Preload', description: 'Whether to load this sound file before the level can begin (typically for the first dialogue of a level).', type: 'boolean' }
     responses: c.array {title: 'Buttons', description: 'An array of buttons to include with the dialogue, with which the user can respond.'}, ResponseSchema
     i18n: {type: 'object', format: 'i18n', props: ['blurb', 'text'], description: 'Help translate this message'}
-  move: c.object {title: 'Move', description: 'Tell the Thang to move.', required: ['target'], default: {target: {x: 20, y: 20}, duration: 500}},
-    target: _.extend _.cloneDeep(PointSchema), {title: 'Target', description: 'Target point to which the Thang will move.'}
-    duration: {title: 'Duration', description: 'Number of milliseconds over which to move, or 0 for an instant move.', type: 'integer', minimum: 0, default: 500, format: 'milliseconds'}
+  move: c.object {title: 'Move', description: 'Tell the Thang to move.', required: ['target'], default: {target: {}, duration: 500}},
+    target: _.extend _.cloneDeep(PointSchema), {title: 'Target', description: 'Target point to which the Thang will move.', default: {x: 20, y: 20}}
+    duration: {title: 'Duration', description: 'Number of milliseconds over which to move, or 0 for an instant move.', type: 'integer', minimum: 0, format: 'milliseconds'}
 
 NoteGroupSchema = c.object {title: 'Note Group', description: 'A group of notes that should be sent out as a result of this script triggering.', displayProperty: 'name'},
   name: {title: 'Name', description: 'Short name describing the script, like \"Anya greets the player\", for your convenience.', type: 'string'}
@@ -116,7 +116,7 @@ NoteGroupSchema = c.object {title: 'Note Group', description: 'A group of notes
   playback: c.object {title: 'Playback', description: 'Control the playback of the level.'},
     playing: {type: 'boolean', title: 'Set Playing', description: 'Set whether playback is playing or paused.'}
     scrub: c.object {title: 'Scrub', description: 'Scrub the level playback time to a certain point.', default: {offset: 2, duration: 1000, toRatio: 0.5}},
-      offset: {type: 'integer', title: 'Offset', description: 'Number of frames by which to adjust the scrub target time.', default: 2}
+      offset: {type: 'integer', title: 'Offset', description: 'Number of frames by which to adjust the scrub target time.'}
       duration: {type: 'integer', title: 'Duration', description: 'Number of milliseconds over which to scrub time.', minimum: 0, format: 'milliseconds'}
       toRatio: {type: 'number', title: 'To Progress Ratio', description: 'Set playback time to a target playback progress ratio.', minimum: 0, maximum: 1}
       toTime: {type: 'number', title: 'To Time', description: 'Set playback time to a target playback point, in seconds.', minimum: 0}
@@ -156,7 +156,7 @@ ScriptSchema = c.object {
   id: c.shortString(title: 'ID', description: 'A unique ID that other scripts can rely on in their Happens After prereqs, for sequencing.')  # uniqueness?
   channel: c.shortString(title: 'Event', format: 'event-channel', description: 'Event channel this script might trigger for, like "world:won".')
   eventPrereqs: c.array {title: 'Event Checks', description: 'Logical checks on the event for this script to trigger.', format: 'event-prereqs'}, EventPrereqSchema
-  repeats: {title: 'Repeats', description: 'Whether this script can trigger more than once during a level.', enum: [true, false, 'session'], 'default': false}
+  repeats: {title: 'Repeats', description: 'Whether this script can trigger more than once during a level.', enum: [true, false, 'session']}
   scriptPrereqs: c.array {title: 'Happens After', description: 'Scripts that need to fire first.'},
     c.shortString(title: 'ID', description: 'A unique ID of a script.')
   notAfter: c.array {title: 'Not After', description: 'Do not run this script if any of these scripts have run.'},
@@ -189,7 +189,7 @@ LevelSystemSchema = c.object {
 },
   original: c.objectId(title: 'Original', description: 'A reference to the original System being configured.', format: 'hidden')
   config: c.object {title: 'Configuration', description: 'System-specific configuration properties.', additionalProperties: true, format: 'level-system-configuration'}
-  majorVersion: {title: 'Major Version', description: 'Which major version of the System is being used.', type: 'integer', minimum: 0, default: 0, format: 'hidden'}
+  majorVersion: {title: 'Major Version', description: 'Which major version of the System is being used.', type: 'integer', minimum: 0, format: 'hidden'}
 
 GeneralArticleSchema = c.object {
   title: 'Article'
@@ -211,16 +211,18 @@ LevelSchema = c.object {
   'default':
     name: 'Ineffable Wizardry'
     description: 'This level is indescribably flarmy.'
-    documentation: {specificArticles: [], generalArticles: []}
+    documentation: {}
     scripts: []
     thangs: []
+    systems: []
+    victory: {}
 }
 c.extendNamedProperties LevelSchema  # let's have the name be the first property
 _.extend LevelSchema.properties,
-  description: {title: 'Description', description: 'A short explanation of what this level is about.', type: 'string', maxLength: 65536, 'default': 'This level is indescribably flarmy!', format: 'markdown'}
+  description: {title: 'Description', description: 'A short explanation of what this level is about.', type: 'string', maxLength: 65536, format: 'markdown'}
   documentation: c.object {title: 'Documentation', description: 'Documentation articles relating to this level.', required: ['specificArticles', 'generalArticles'], 'default': {specificArticles: [], generalArticles: []}},
-    specificArticles: c.array {title: 'Specific Articles', description: 'Specific documentation articles that live only in this level.', uniqueItems: true, 'default': []}, SpecificArticleSchema
-    generalArticles: c.array {title: 'General Articles', description: 'General documentation articles that can be linked from multiple levels.', uniqueItems: true, 'default': []}, GeneralArticleSchema
+    specificArticles: c.array {title: 'Specific Articles', description: 'Specific documentation articles that live only in this level.', uniqueItems: true }, SpecificArticleSchema
+    generalArticles: c.array {title: 'General Articles', description: 'General documentation articles that can be linked from multiple levels.', uniqueItems: true}, GeneralArticleSchema
   background: c.objectId({format: 'hidden'})
   nextLevel: {
     type: 'object',
@@ -230,10 +232,13 @@ _.extend LevelSchema.properties,
     description: 'Reference to the next level players will play after beating this one.'
   }
   employerDescription: { type:'string', format: 'markdown', title: 'Employer Description' }
-  scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema
-  thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema
-  systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema  # TODO: uniqueness should be based on 'original', not whole thing
-  victory: c.object {title: 'Victory Screen', default: {}, properties: {'body': {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'}, i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}}}
+  scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.'}, ScriptSchema
+  thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.' }, LevelThangSchema
+  systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true }, LevelSystemSchema  # TODO: uniqueness should be based on 'original', not whole thing
+  victory: c.object {title: 'Victory Screen'}, {
+    body: {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'},
+    i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}
+  }
   i18n: {type: 'object', format: 'i18n', props: ['name', 'description'], description: 'Help translate this level'}
   icon: {type: 'string', format: 'image-file', title: 'Icon'}
   banner: {type: 'string', format: 'image-file', title: 'Banner'}
diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee
index 59603ccd1..3ae076ea1 100644
--- a/app/views/kinds/RootView.coffee
+++ b/app/views/kinds/RootView.coffee
@@ -89,7 +89,7 @@ module.exports = class RootView extends CocoView
     if $select.hasClass('fancified')
       $select.parent().find('.options, .trigger').remove()
       $select.unwrap().removeClass('fancified')
-    preferred = me.lang()
+    preferred = me.get('preferredLanguage', true)
     codes = _.keys(locale)
     genericCodes = _.filter codes, (code) ->
       _.find(codes, (code2) ->
diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee
index 604625705..7bde697d2 100644
--- a/app/views/play/level/PlayLevelView.coffee
+++ b/app/views/play/level/PlayLevelView.coffee
@@ -152,7 +152,7 @@ module.exports = class PlayLevelView extends RootView
   getRenderData: ->
     c = super()
     c.world = @world
-    if me.get('hourOfCode') and me.lang() is 'en-US'
+    if me.get('hourOfCode') and me.get('preferredLanguage', true) is 'en-US'
       # Show the Hour of Code footer explanation until it's been more than a day
       elapsed = (new Date() - new Date(me.get('dateCreated')))
       c.explainHourOfCode = elapsed < 86400 * 1000