diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee
index f9b657ce8..f10035168 100644
--- a/app/models/CocoModel.coffee
+++ b/app/models/CocoModel.coffee
@@ -273,7 +273,7 @@ class CocoModel extends Backbone.Model
     achievements = new NewAchievementCollection
     achievements.fetch(
       success: (collection) ->
-        Backbone.Mediator.publish('achievements:new', collection) unless _.isEmpty(collection.models)
+        me.fetch (success: -> Backbone.Mediator.publish('achievements:new', collection)) unless _.isEmpty(collection.models)
     )
 
 
diff --git a/app/models/User.coffee b/app/models/User.coffee
index 161a347f5..f224c85c9 100644
--- a/app/models/User.coffee
+++ b/app/models/User.coffee
@@ -78,13 +78,17 @@ module.exports = class User extends CocoModel
   a = 5
   b = 40
 
-  # y = a * ln(1/b * (x + b))
+  # y = a * ln(1/b * (x + b)) + 1
   @levelFromExp: (xp) ->
-    if xp > 0 then Math.floor(a * Math.log((1/b) * (xp + b))) else 0
+    if xp > 0 then Math.floor(a * Math.log((1/b) * (xp + b))) + 1 else 1
 
-  # x = (e^(y/a) - 1) * b
+  # x = (e^((y-1)/a) - 1) * b
   @expForLevel: (level) ->
-    Math.ceil((Math.exp(level / a) - 1) * b)
+    Math.ceil((Math.exp((level - 1)/ a) - 1) * b)
 
   level: ->
-    User.levelFromExp(@get('points'))
\ No newline at end of file
+    User.levelFromExp(@get('points'))
+
+  levelFromExp: (xp) -> User.levelFromExp(xp)
+
+  expForLevel: (level) -> User.expForLevel(level)
diff --git a/app/schemas/models/achievement.coffee b/app/schemas/models/achievement.coffee
index 38f4a4e50..c064e969f 100644
--- a/app/schemas/models/achievement.coffee
+++ b/app/schemas/models/achievement.coffee
@@ -25,6 +25,7 @@ MongoFindQuerySchema =
       oneOf: [
         #{ $ref: '#/definitions/' + MongoQueryOperatorSchema.id},
         { type: 'string' }
+        { type: 'object' }
       ]
   additionalProperties: true # TODO make Treema accept new pattern matched keys
   definitions: {}
@@ -49,6 +50,24 @@ _.extend(AchievementSchema.properties,
   proportionalTo:
     type: 'string'
     description: 'For repeatables only. Denotes the field a repeatable achievement needs for its calculations'
+  function:
+    type: 'object'
+    oneOf: [
+      linear:
+        type: 'object'
+        properties:
+          a: {type: 'number', default: 1},
+          required: ['a']
+        description: 'f(x) = a * x'
+      logarithmic:
+        type:'object'
+        properties:
+          a: {type: 'number', default: 1}
+          b: {type: 'number', default: 1}
+        required: ['a', 'b']
+        description: 'f(x) = a * ln(1/b * (x + b))'
+    ]
+    default: linear: a: 1
 )
 
 AchievementSchema.definitions = {}
diff --git a/app/styles/notify.sass b/app/styles/notify.sass
index c36e6b413..0a0b47cf1 100644
--- a/app/styles/notify.sass
+++ b/app/styles/notify.sass
@@ -1,10 +1,12 @@
 .notifyjs-achievement-base
-  background: url("/images/pages/base/notify_mockup.png")
+  //background: url("/images/pages/base/notify_mockup.png")
+  background-image: url("/images/pages/base/modal_background.png")
   background-size: 100% 100%
   width: 500px
   height: 200px
-  padding: 35px 20px 15px 15px
+  padding: 35px 35px 15px 15px
   text-align: center
+  cursor: auto
 
   .achievement-body
     .achievement-image
@@ -13,7 +15,10 @@
         width: 100px
         height: 100px
         border-radius: 50%
-        margin: 30px 40px 20px 30px
+        margin: 20px 30px 20px 30px
+        -webkit-box-shadow: 0px 0px 36px 0px white
+        -moz-box-shadow: 0px 0px 36px 0px white
+        box-shadow: 0px 0px 36px 0px white
 
     .achievement-title
       font-family: Bangers
@@ -23,13 +28,14 @@
       margin-top: 10px
       font-size: 16px
 
-    .achievement-message
-      &:empty
-        display: none
-
-
     .achievement-progress
-      padding: 25px 0px 0px 0px
+      padding: 15px 0px 0px 0px
+
+      .achievement-message
+        font-family: Bangers
+        font-size: 18px
+        &:empty
+          display: none
 
       .progress-wrapper
         .progress-bar-wrapper
@@ -38,4 +44,4 @@
           padding-left: 5px
           font-family: Bangers
           font-size: 16px
-          float: right
\ No newline at end of file
+          float: right
diff --git a/app/views/editor/achievement/edit.coffee b/app/views/editor/achievement/edit.coffee
index 9c03af6a7..8a81befce 100644
--- a/app/views/editor/achievement/edit.coffee
+++ b/app/views/editor/achievement/edit.coffee
@@ -48,6 +48,7 @@ module.exports = class AchievementEditView extends View
     @treema = @$el.find('#achievement-treema').treema(options)
 
     @treema.build()
+    console.log @treema
 
   pushChangesToPreview: =>
     'TODO' # TODO might want some intrinsic preview thing
@@ -73,4 +74,4 @@ module.exports = class AchievementEditView extends View
 
     res.success =>
       url = "/editor/achievement/#{@achievement.get('slug') or @achievement.id}"
-      document.location.href = url
\ No newline at end of file
+      document.location.href = url
diff --git a/app/views/editor/achievement/home.coffee b/app/views/editor/achievement/home.coffee
index f02be15b6..de8b7ce3b 100644
--- a/app/views/editor/achievement/home.coffee
+++ b/app/views/editor/achievement/home.coffee
@@ -8,11 +8,18 @@ module.exports = class AchievementSearchView extends SearchView
   tableTemplate: require 'templates/editor/achievement/table'
   projection: ['name', 'description', 'collection', 'slug']
 
+  initialize: ->
+    console.log me.isAdmin()
+    unless me.isAdmin()
+      NotFoundView = require '../../not_found'
+      return new NotFoundView
+    else super()
+
   getRenderData: ->
     context = super()
     context.currentEditor = 'editor.achievement_title'
     context.currentNew = 'editor.new_achievement_title'
-    context.currentNewSignup = 'editor.new_achievement_title_signup'
+    context.currentNewSignup = 'editor.new_achievement_title_login'
     context.currentSearch = 'editor.achievement_search_title'
     @$el.i18n()
-    context
\ No newline at end of file
+    context
diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee
index b6becd78f..fd036784b 100644
--- a/app/views/kinds/RootView.coffee
+++ b/app/views/kinds/RootView.coffee
@@ -39,17 +39,24 @@ module.exports = class RootView extends CocoView
     totalExpNeeded = nextLevelExp - currentLevelExp
     currentExp = me.get('points')
     worth = achievement.get('worth')
-    alreadyAchievedPercentage = 100 * (currentExp - currentLevelExp - achievement.get('worth')) / totalExpNeeded
-    newlyAchievedPercentage = 100 * achievement.get('worth') / totalExpNeeded
+    leveledUp = currentExp - worth < currentLevelExp
+    alreadyAchievedPercentage = 100 * (currentExp - currentLevelExp - worth) / totalExpNeeded
+    newlyAchievedPercentage = if currentLevelExp is currentExp then 0 else 100 * worth / totalExpNeeded
 
     console.debug "Current level is #{currentLevel} (#{currentLevelExp} xp), next level is #{nextLevel} (#{nextLevelExp} xp)."
-    console.debug "Need a total of #{nextLevelExp - currentLevelExp}, already had #{currentExp - currentLevelExp - worth} and just now earned #{worth}"
+    console.debug "Need a total of #{nextLevelExp - currentLevelExp}, already had #{currentExp - currentLevelExp - worth} and just now earned #{worth} totalling on #{currentExp}"
 
     alreadyAchievedBar = $("<div class='progress-bar progress-bar-warning' style='width:#{alreadyAchievedPercentage}%'></div>")
-    newlyAchievedBar = $("<div class='progress-bar progress-bar-success' style='width:#{newlyAchievedPercentage}%'></div>")
-    progressBar = $('<div class="progress"></div>').append(alreadyAchievedBar).append(newlyAchievedBar)
-    message = "Reached level #{currentLevel}!" if currentExp - worth < currentLevelExp
+    newlyAchievedBar = $("<div data-toggle='tooltip' class='progress-bar progress-bar-success' style='width:#{newlyAchievedPercentage}%'></div>")
+    emptyBar = $("<div data-toggle='tooltip' class='progress-bar progress-bar-white' style='width:#{100 - newlyAchievedPercentage - alreadyAchievedPercentage}%'></div>")
+    progressBar = $('<div class="progress" data-toggle="tooltip"></div>').append(alreadyAchievedBar).append(newlyAchievedBar).append(emptyBar)
+    message = if (currentLevel isnt 1) and leveledUp then "Reached level #{currentLevel}!" else null
 
+    alreadyAchievedBar.tooltip(title: "#{currentExp} XP in total")
+    newlyAchievedBar.tooltip(title: "#{worth} XP earned")
+    emptyBar.tooltip(title: "#{nextLevelExp - currentExp} XP until level #{nextLevel}")
+
+    # TODO a default should be linked here
     imageURL = '/file/' + achievement.get('icon')
     data =
       title: achievement.get('name')
@@ -60,11 +67,11 @@ module.exports = class RootView extends CocoView
       message: message
 
     options =
-      autoHideDelay: 15000
+      autoHideDelay: 10000
       globalPosition: 'bottom right'
       showDuration: 400
       style: 'achievement'
-      autoHide: false
+      autoHide: true
       clickToHide: true
 
     $.notify( data, options )
diff --git a/server/achievements/Achievement.coffee b/server/achievements/Achievement.coffee
index eff3bc857..faa625654 100644
--- a/server/achievements/Achievement.coffee
+++ b/server/achievements/Achievement.coffee
@@ -29,7 +29,7 @@ AchievementSchema.pre('save', (next) ->
   next()
 )
 
-AchievementSchema.plugin(plugins.SearchablePlugin, {searchable: ['name']})
 AchievementSchema.plugin(plugins.NamedPlugin)
+AchievementSchema.plugin(plugins.SearchablePlugin, {searchable: ['name']})
 
-module.exports = Achievement = mongoose.model('Achievement', AchievementSchema)
\ No newline at end of file
+module.exports = Achievement = mongoose.model('Achievement', AchievementSchema)
diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee
index 199ae90b8..e8fdbd668 100644
--- a/server/commons/Handler.coffee
+++ b/server/commons/Handler.coffee
@@ -159,7 +159,7 @@ module.exports = class Handler
       return @sendNotFoundError(res)
     term = req.query.term
     matchedObjects = []
-    filters = [{filter: {index: true}}]
+    filters = if @modelClass.schema.uses_coco_versions or @modelClass.schema.uses_coco_permissions then [filter: {index: true}] else [filter: {}]
     if @modelClass.schema.uses_coco_permissions and req.user
       filters.push {filter: {index: req.user.get('id')}}
     projection = null
diff --git a/server/plugins/achievements.coffee b/server/plugins/achievements.coffee
index 0975624da..70efd15fc 100644
--- a/server/plugins/achievements.coffee
+++ b/server/plugins/achievements.coffee
@@ -15,7 +15,6 @@ loadAchievements = ->
       category = achievement.get 'collection'
       achievements[category] = [] unless category of achievements
       achievements[category].push achievement
-
 loadAchievements()
 
 module.exports = AchievablePlugin = (schema, options) ->
@@ -62,11 +61,11 @@ module.exports = AchievablePlugin = (schema, options) ->
               console.error err if err?
             )
 
-          if isRepeatable # TODO test more thoroughly
+          if isRepeatable
             console.log 'Upserting repeatable achievement called \'' + (achievement.get 'name') + '\' for ' + userID
             proportionalTo = achievement.get 'proportionalTo'
             originalAmount = util.getByPath(originalDocObj, proportionalTo) or 0
-            newAmount = docObj.get proportionalTo
+            newAmount = docObj[proportionalTo]
 
             if originalAmount isnt newAmount
               earned.notified = false
@@ -87,10 +86,5 @@ module.exports = AchievablePlugin = (schema, options) ->
               earnedPoints = achievement.get('worth')
               wrapUp()
 
-
-
-
-
-
     delete before[doc.id] unless isNew # This assumes everything we patch has a _id
-    return
\ No newline at end of file
+    return
diff --git a/server/users/User.coffee b/server/users/User.coffee
index 744b8db7b..f0cc8e514 100644
--- a/server/users/User.coffee
+++ b/server/users/User.coffee
@@ -127,3 +127,6 @@ UserSchema.statics.hashPassword = (password) ->
   shasum.digest('hex')
 
 module.exports = User = mongoose.model('User', UserSchema)
+
+AchievablePlugin = require '../plugins/achievements'
+UserSchema.plugin(AchievablePlugin)