diff --git a/app/lib/LevelBus.coffee b/app/lib/LevelBus.coffee
index 2ac996640..8b270808b 100644
--- a/app/lib/LevelBus.coffee
+++ b/app/lib/LevelBus.coffee
@@ -32,7 +32,7 @@ module.exports = class LevelBus extends Bus
     @fireScriptsRef = @fireRef?.child('scripts')
 
   setSession: (@session) ->
-    @session.on 'change:multiplayer', @onMultiplayerChanged, @
+    @listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
 
   onPoint: ->
     return true unless @session?.get('multiplayer')
@@ -226,5 +226,4 @@ module.exports = class LevelBus extends Bus
     tempSession.save(patch, {patch: true})
 
   destroy: ->
-    @session.off 'change:multiplayer', @onMultiplayerChanged, @
     super()
diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee
index 9d65a3d5d..ce842fbd0 100644
--- a/app/lib/LevelLoader.coffee
+++ b/app/lib/LevelLoader.coffee
@@ -60,13 +60,13 @@ module.exports = class LevelLoader extends CocoClass
     # Unless you specify cache:false, sometimes the browser will use a cached session
     # and players will 'lose' code
     @session.fetch({cache:false})
-    @session.once 'sync', @onSessionLoaded, @
+    @listenToOnce(@session, 'sync', @onSessionLoaded)
 
     if @opponentSessionID
       @opponentSession = new LevelSession()
       @opponentSession.url = "/db/level_session/#{@opponentSessionID}"
       @opponentSession.fetch()
-      @opponentSession.once 'sync', @onSessionLoaded, @
+      @listenToOnce(@opponentSession, 'sync', @onSessionLoaded)
 
   sessionsLoaded: ->
     return true if @headless
@@ -82,8 +82,8 @@ module.exports = class LevelLoader extends CocoClass
   # Supermodel (Level) Loading
 
   loadLevelModels: ->
-    @supermodel.on 'loaded-one', @onSupermodelLoadedOne, @
-    @supermodel.once 'error', @onSupermodelError, @
+    @listenTo(@supermodel, 'loaded-one', @onSupermodelLoadedOne)
+    @listenToOnce(@supermodel, 'error', @onSupermodelError)
     @level = @supermodel.getModel(Level, @levelID) or new Level _id: @levelID
     levelID = @levelID
     headless = @headless
@@ -235,7 +235,6 @@ module.exports = class LevelLoader extends CocoClass
     @trigger 'loaded-all' if @progress() is 1
 
   destroy: ->
-    @supermodel.off 'loaded-one', @onSupermodelLoadedOne
     @world = null  # don't hold onto garbage
     @update = null
     super()
diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee
index 888ba3f52..e9596eae1 100644
--- a/app/lib/simulator/Simulator.coffee
+++ b/app/lib/simulator/Simulator.coffee
@@ -48,9 +48,9 @@ module.exports = class Simulator extends CocoClass
     @god = new God maxWorkerPoolSize: 1, maxAngels: 1  # Start loading worker.
 
     @levelLoader = new LevelLoader supermodel: @supermodel, levelID: @task.getLevelName(), sessionID: @task.getFirstSessionID(), headless: true
-    @levelLoader.once 'loaded-all', @simulateGame
+    @listenToOnce(@levelLoader, 'loaded-all', @simulateGame)
 
-  simulateGame: =>
+  simulateGame: ->
     return if @destroyed
     @trigger 'statusUpdate', 'All resources loaded, simulating!', @task.getSessions()
     @assignWorldAndLevelFromLevelLoaderAndDestroyIt()
diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee
index 0b6e450e2..e7ca4ccfe 100644
--- a/app/lib/surface/CocoSprite.coffee
+++ b/app/lib/surface/CocoSprite.coffee
@@ -73,7 +73,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
     else
       @stillLoading = true
       @thangType.fetch()
-      @thangType.once 'sync', @setupSprite, @
+      @listenToOnce(@thangType, 'sync', @setupSprite)
 
   setupSprite: ->
     @stillLoading = false
diff --git a/app/lib/surface/Mark.coffee b/app/lib/surface/Mark.coffee
index 58df6ded3..4e7d16e6d 100644
--- a/app/lib/surface/Mark.coffee
+++ b/app/lib/surface/Mark.coffee
@@ -22,7 +22,6 @@ module.exports = class Mark extends CocoClass
   destroy: ->
     @mark?.parent?.removeChild @mark
     @markSprite?.destroy()
-    @thangType?.off 'sync', @onLoadedThangType, @
     @sprite = null
     super()
 
@@ -177,7 +176,7 @@ module.exports = class Mark extends CocoClass
       return @loadThangType() if not thangType
       @thangType = thangType
 
-    return @thangType.once 'sync', @onLoadedThangType, @ if not @thangType.loaded
+    return @listenToOnce(@thangType, 'sync', @onLoadedThangType) if not @thangType.loaded
     CocoSprite = require './CocoSprite'
     markSprite = new CocoSprite @thangType, @thangType.spriteOptions
     markSprite.queueAction 'idle'
@@ -188,7 +187,7 @@ module.exports = class Mark extends CocoClass
     name = @thangType
     @thangType = new ThangType()
     @thangType.url = -> "/db/thang.type/#{name}"
-    @thangType.once 'sync', @onLoadedThangType, @
+    @listenToOnce(@thangType, 'sync', @onLoadedThangType)
     @thangType.fetch()
     markThangTypes[name] = @thangType
     window.mtt = markThangTypes
diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index 9ce14c75d..9e2bcd347 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -9,8 +9,8 @@ class SuperModel
     @mustPopulate = model
     model.saveBackups = @shouldSaveBackups(model)
     model.fetch() unless model.loaded or model.loading
-    model.once('sync', @modelLoaded, @) unless model.loaded
-    model.once('error', @modelErrored, @) unless model.loaded
+    @listenToOnce(model, 'sync', @modelLoaded) unless model.loaded
+    @listenToOnce(model, 'error', @modelErrored) unless model.loaded
     url = model.url()
     @models[url] = model unless @models[url]?
     @modelLoaded(model) if model.loaded
@@ -40,7 +40,7 @@ class SuperModel
       continue if @models[refURL]
       @models[refURL] = ref
       ref.fetch()
-      ref.once 'sync', @modelLoaded, @
+      @listenToOnce(ref, 'sync', @modelLoaded)
 
     @trigger 'loaded-one', model: model
     @trigger 'loaded-all' if @finished()
diff --git a/app/treema-ext.coffee b/app/treema-ext.coffee
index 1455bc534..d85eb8d21 100644
--- a/app/treema-ext.coffee
+++ b/app/treema-ext.coffee
@@ -20,7 +20,7 @@ class LiveEditingMarkup extends TreemaNode.nodeMap.ace
 
   buildValueForEditing: (valEl) ->
     super(valEl)
-    @editor.on 'change', @onEditorChange
+    @listenTo(@editor, 'change', @onEditorChange)
     @addImageUpload(valEl)
 
   addImageUpload: (valEl) ->
@@ -47,7 +47,7 @@ class LiveEditingMarkup extends TreemaNode.nodeMap.ace
   onFileUploaded: (e) =>
     @editor.insert "![#{e.metadata.name}](/file/#{@uploadingPath})"
 
-  onEditorChange: =>
+  onEditorChange: ->
     @saveChanges()
     @flushChanges()
     @getRoot().broadcastChanges()
@@ -203,10 +203,10 @@ class CoffeeTreema extends TreemaNode.nodeMap.ace
 
   buildValueForEditing: (valEl) ->
     super(valEl)
-    @editor.on 'change', @onEditorChange
+    @listenTo(@editor, 'change', @onEditorChange)
     valEl
 
-  onEditorChange: =>
+  onEditorChange: ->
     @saveChanges()
     @flushChanges()
     @getRoot().broadcastChanges()
@@ -297,9 +297,9 @@ class LatestVersionReferenceNode extends TreemaNode
     @collection.url = "#{@url}?term=#{''}&project=true"
     
     @collection.fetch()
-    @collection.on 'sync', @searchCallback
+    @listenTo(@collection, 'sync', @searchCallback)
 
-  searchCallback: =>
+  searchCallback: ->
     container = @getSearchResultsEl().detach().empty()
     first = true
     for model in @collection.models
diff --git a/app/views/account/settings_view.coffee b/app/views/account/settings_view.coffee
index 8357af325..df815b3cb 100644
--- a/app/views/account/settings_view.coffee
+++ b/app/views/account/settings_view.coffee
@@ -46,7 +46,7 @@ module.exports = class SettingsView extends View
 
     @chooseTab(location.hash.replace('#',''))
     WizardSettingsView = new WizardSettingsView()
-    WizardSettingsView.on 'change', @save, @
+    @listenTo(WizardSettingsView, 'change', @save)
     @insertSubView WizardSettingsView
 
   chooseTab: (category) ->
@@ -81,7 +81,7 @@ module.exports = class SettingsView extends View
     $('#email-pane input[type="checkbox"]', @$el).prop('checked', not Boolean(subs.length))
     @save()
 
-  save: =>
+  save: ->
     forms.clearFormAlerts(@$el)
     @grabData()
     res = me.validate()
diff --git a/app/views/admin/clas_view.coffee b/app/views/admin/clas_view.coffee
index 873fa6584..e099b4d10 100644
--- a/app/views/admin/clas_view.coffee
+++ b/app/views/admin/clas_view.coffee
@@ -16,7 +16,7 @@ module.exports = class CLAsView extends View
     })
     @clas = new CLACollection()
     @clas.fetch()
-    @clas.on 'sync', @onCLAsLoaded, @
+    @listenTo(@clas, 'sync', @onCLAsLoaded)
 
   onCLAsLoaded: ->
     @startsLoading = false
diff --git a/app/views/editor/components/main.coffee b/app/views/editor/components/main.coffee
index 06337a6c8..971d236bb 100644
--- a/app/views/editor/components/main.coffee
+++ b/app/views/editor/components/main.coffee
@@ -24,7 +24,7 @@ module.exports = class ThangComponentEditView extends CocoView
     if not @componentCollection
       @componentCollection = @supermodel.getCollection new ComponentsCollection()
     unless @componentCollection.loaded
-      @componentCollection.once 'sync', @onComponentsSync
+      @listenToOnce(@componentCollection, 'sync', @onComponentsSync)
       @componentCollection.fetch()
     super() # do afterRender at the end
 
@@ -35,7 +35,7 @@ module.exports = class ThangComponentEditView extends CocoView
     @buildExtantComponentTreema()
     @buildAddComponentTreema()
 
-  onComponentsSync: =>
+  onComponentsSync: ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
     @render()
diff --git a/app/views/editor/level/add_thangs_view.coffee b/app/views/editor/level/add_thangs_view.coffee
index 4a0d6f776..35e8917c9 100644
--- a/app/views/editor/level/add_thangs_view.coffee
+++ b/app/views/editor/level/add_thangs_view.coffee
@@ -23,10 +23,10 @@ module.exports = class AddThangsView extends View
     super options
     @world = options.world
     @thangTypes = @supermodel.getCollection new ThangTypeSearchCollection()  # should load depended-on Components, too
-    @thangTypes.once 'sync', @onThangTypesLoaded
+    @listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
     @thangTypes.fetch()
 
-  onThangTypesLoaded: =>
+  onThangTypesLoaded: ->
     return if @destroyed
     @render()  # do it again but without the loading screen
 
diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee
index 46db9a7fb..f2e392f4b 100644
--- a/app/views/editor/level/component/edit.coffee
+++ b/app/views/editor/level/component/edit.coffee
@@ -79,9 +79,9 @@ module.exports = class LevelComponentEditView extends View
     session.setTabSize 2
     session.setNewLineMode = 'unix'
     session.setUseSoftTabs true
-    @editor.on 'change', @onEditorChange
+    @listenTo(@editor, 'change', @onEditorChange)
     
-  onEditorChange: =>
+  onEditorChange: ->
     @levelComponent.set 'code', @editor.getValue()
     Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
     null
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 8f4f68a00..6d6b5a774 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -28,7 +28,7 @@ module.exports = class EditorLevelView extends View
 
   constructor: (options, @levelID) ->
     super options
-    @supermodel.once 'loaded-all', @onAllLoaded
+    @listenToOnce(@supermodel, 'loaded-all', @onAllLoaded)
 
     # load only the level itself and the one it points to, but no others
     # TODO: this is duplicated in views/play/level_view.coffee; need cleaner method
@@ -42,18 +42,18 @@ module.exports = class EditorLevelView extends View
       model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem']
 
     @level = new Level _id: @levelID
-    @level.once 'sync', @onLevelLoaded
+    @listenToOnce(@level, 'sync', @onLevelLoaded)
     @supermodel.populateModel @level
 
   showLoading: ($el) ->
     $el ?= @$el.find('.tab-content')
     super($el)
 
-  onLevelLoaded: =>
+  onLevelLoaded: ->
     @files = new DocumentFiles(@level)
     @files.fetch()
 
-  onAllLoaded: =>
+  onAllLoaded: ->
     @level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
     @initWorld()
     @startsLoading = false
diff --git a/app/views/editor/level/system/add.coffee b/app/views/editor/level/system/add.coffee
index 4ea54e3ec..a106e3d39 100644
--- a/app/views/editor/level/system/add.coffee
+++ b/app/views/editor/level/system/add.coffee
@@ -24,7 +24,7 @@ module.exports = class LevelSystemAddView extends View
     if not @systems
       @systems = @supermodel.getCollection new LevelSystemSearchCollection()
     unless @systems.loaded
-      @systems.once 'sync', @onSystemsSync
+      @listenToOnce(@systems, 'sync', @onSystemsSync)
       @systems.fetch()
     super() # do afterRender at the end
 
@@ -44,7 +44,7 @@ module.exports = class LevelSystemAddView extends View
     for system in systems
       ul.append $(availableSystemTemplate(system: system))
 
-  onSystemsSync: =>
+  onSystemsSync: ->
     @supermodel.addCollection @systems
     @render()
 
diff --git a/app/views/editor/level/system/edit.coffee b/app/views/editor/level/system/edit.coffee
index 52a48cad9..e4de039d3 100644
--- a/app/views/editor/level/system/edit.coffee
+++ b/app/views/editor/level/system/edit.coffee
@@ -77,9 +77,9 @@ module.exports = class LevelSystemEditView extends View
     session.setTabSize 2
     session.setNewLineMode = 'unix'
     session.setUseSoftTabs true
-    @editor.on 'change', @onEditorChange
+    @listenTo(@editor, 'change', @onEditorChange)
 
-  onEditorChange: =>
+  onEditorChange: ->
     @levelSystem.set 'code', @editor.getValue()
     Backbone.Mediator.publish 'level-system-edited', levelSystem: @levelSystem
     null
diff --git a/app/views/editor/level/systems_tab_view.coffee b/app/views/editor/level/systems_tab_view.coffee
index 59ed6fb48..52129e7b8 100644
--- a/app/views/editor/level/systems_tab_view.coffee
+++ b/app/views/editor/level/systems_tab_view.coffee
@@ -34,11 +34,11 @@ module.exports = class SystemsTabView extends View
       do (url) -> ls.url = -> url
       continue if @supermodel.getModelByURL ls.url
       ls.fetch()
-      ls.on 'sync', @onSystemLoaded
+      @listenTo(ls, 'sync', @onSystemLoaded)
       ++@toLoad
     @onDefaultSystemsLoaded() unless @toLoad
 
-  onSystemLoaded: (ls) =>
+  onSystemLoaded: (ls) ->
     @supermodel.addModel ls
     --@toLoad
     @onDefaultSystemsLoaded() unless @toLoad
diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee
index e0af8ddc4..a831c33c0 100644
--- a/app/views/editor/level/thangs_tab_view.coffee
+++ b/app/views/editor/level/thangs_tab_view.coffee
@@ -59,15 +59,15 @@ module.exports = class ThangsTabView extends View
     super options
     @world = options.world
     @thangTypes = @supermodel.getCollection new ThangTypeSearchCollection()  # should load depended-on Components, too
-    @thangTypes.once 'sync', @onThangTypesLoaded
+    @listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
     @thangTypes.fetch()
 
     # just loading all Components for now: https://github.com/codecombat/codecombat/issues/405
     @componentCollection = @supermodel.getCollection new ComponentsCollection()
-    @componentCollection.once 'sync', @onComponentsLoaded
+    @listenToOnce(@componentCollection, 'sync', @onComponentsLoaded)
     @componentCollection.fetch()
 
-  onThangTypesLoaded: =>
+  onThangTypesLoaded: ->
     return if @destroyed
     @supermodel.addCollection @thangTypes
     @supermodel.populateModel model for model in @thangTypes.models
@@ -75,7 +75,7 @@ module.exports = class ThangsTabView extends View
     @render()  # do it again but without the loading screen
     @onLevelLoaded level: @level if @level and not @startsLoading
 
-  onComponentsLoaded: =>
+  onComponentsLoaded: ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
     @startsLoading = not @thangTypes.loaded
diff --git a/app/views/play/ladder/play_modal.coffee b/app/views/play/ladder/play_modal.coffee
index ebe51e68d..2272be191 100644
--- a/app/views/play/ladder/play_modal.coffee
+++ b/app/views/play/ladder/play_modal.coffee
@@ -30,7 +30,7 @@ module.exports = class LadderPlayModal extends View
 
   loadChallengers: ->
     @challengersCollection = new ChallengersData(@level, @team, @otherTeam, @session)
-    @challengersCollection.on 'sync', @loadNames, @
+    @listenTo(@challengersCollection, 'sync', @loadNames)
 
   # PART 2: Loading the names of the other users
 
@@ -53,7 +53,7 @@ module.exports = class LadderPlayModal extends View
   # PART 3: Make sure wizard is loaded
 
   checkWizardLoaded: ->
-    if @wizardType.loaded then @finishRendering() else @wizardType.once 'sync', @finishRendering, @
+    if @wizardType.loaded then @finishRendering() else @listenToOnce(@wizardType, 'sync', @finishRendering)
 
   # PART 4: Render
 
@@ -158,13 +158,13 @@ class ChallengersData
     score = @session?.get('totalScore') or 25
     @easyPlayer = new LeaderboardCollection(@level, {order:1, scoreOffset: score - 5, limit: 1, team: @otherTeam})
     @easyPlayer.fetch()
-    @easyPlayer.once 'sync', @challengerLoaded, @
+    @listenToOnce(@easyPlayer, 'sync', @challengerLoaded)
     @mediumPlayer = new LeaderboardCollection(@level, {order:1, scoreOffset: score, limit: 1, team: @otherTeam})
     @mediumPlayer.fetch()
-    @mediumPlayer.once 'sync', @challengerLoaded, @
+    @listenToOnce(@mediumPlayer, 'sync', @challengerLoaded)
     @hardPlayer = new LeaderboardCollection(@level, {order:-1, scoreOffset: score + 5, limit: 1, team: @otherTeam})
     @hardPlayer.fetch()
-    @hardPlayer.once 'sync', @challengerLoaded, @
+    @listenToOnce(@hardPlayer, 'sync', @challengerLoaded)
 
   challengerLoaded: ->
     if @allLoaded()
diff --git a/app/views/play/ladder_view.coffee b/app/views/play/ladder_view.coffee
index fc05cb0c2..6d1e90313 100644
--- a/app/views/play/ladder_view.coffee
+++ b/app/views/play/ladder_view.coffee
@@ -42,7 +42,7 @@ module.exports = class LadderView extends RootView
     @sessions = new LevelSessionsCollection(levelID)
     p2 = @sessions.fetch({})
     @simulator = new Simulator()
-    @simulator.on 'statusUpdate', @updateSimulationStatus, @
+    @listenTo(@simulator, 'statusUpdate', @updateSimulationStatus)
     @teams = []
     $.when(p1, p2).then @onLoaded
 
@@ -104,7 +104,7 @@ module.exports = class LadderView extends RootView
 
     @simulator.fetchAndSimulateTask()
 
-  updateSimulationStatus: (simulationStatus, sessions)->
+  updateSimulationStatus: (simulationStatus, sessions) ->
     @simulationStatus = simulationStatus
     try
       if sessions?
diff --git a/app/views/play/level/level_chat_view.coffee b/app/views/play/level/level_chat_view.coffee
index 06467fed7..2963c9b74 100644
--- a/app/views/play/level/level_chat_view.coffee
+++ b/app/views/play/level/level_chat_view.coffee
@@ -18,7 +18,7 @@ module.exports = class LevelChatView extends View
   constructor: (options) ->
     @levelID = options.levelID
     @session = options.session
-    @session.on 'change:multiplayer', @updateMultiplayerVisibility, @
+    @listenTo(@session, 'change:multiplayer', @updateMultiplayerVisibility)
     @sessionID = options.sessionID
     @bus = LevelBus.get(@levelID, @sessionID)
     super()
@@ -122,7 +122,6 @@ module.exports = class LevelChatView extends View
 
   destroy: ->
     key.deleteScope('level')
-    @session.off 'change:multiplayer', @updateMultiplayerVisibility, @
     clearInterval @clearOldMessagesInterval if @clearOldMessagesInterval
     @clearOldMessages = null
     super()
diff --git a/app/views/play/level/modal/multiplayer_modal.coffee b/app/views/play/level/modal/multiplayer_modal.coffee
index 2a30d96f7..973bc8b47 100644
--- a/app/views/play/level/modal/multiplayer_modal.coffee
+++ b/app/views/play/level/modal/multiplayer_modal.coffee
@@ -15,7 +15,7 @@ module.exports = class MultiplayerModal extends View
     super(options)
     @session = options.session
     @level = options.level
-    @session.on 'change:multiplayer', @updateLinkSection, @
+    @listenTo(@session, 'change:multiplayer', @updateLinkSection)
     @playableTeams = options.playableTeams
     @ladderGame = options.ladderGame
     console.log 'ladder game is', @ladderGame
@@ -51,5 +51,4 @@ module.exports = class MultiplayerModal extends View
     @session.set('multiplayer', multiplayer)
 
   destroy: ->
-    @session.off 'change:multiplayer', @updateLinkSection, @
     super()
diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee
index 4b08efaac..5e055ac3c 100644
--- a/app/views/play/level/tome/spell_view.coffee
+++ b/app/views/play/level/tome/spell_view.coffee
@@ -43,7 +43,7 @@ module.exports = class SpellView extends View
   constructor: (options) ->
     super options
     @session = options.session
-    @session.on 'change:multiplayer', @onMultiplayerChanged, @
+    @listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
     @spell = options.spell
     @problems = {}
     @writable = false unless me.team in @spell.permissions.readwrite  # TODO: make this do anything
@@ -582,7 +582,6 @@ module.exports = class SpellView extends View
     @aceSession = null
     @debugView?.destroy()
     @spell = null
-    @session.off 'change:multiplayer', @onMultiplayerChanged, @
     for fat in ['notifySpellChanged', 'notifyEditingEnded', 'notifyEditingBegan', 'onFirepadLoaded', 'onLoaded', 'toggleBackground', 'setRecompileNeeded', 'onCursorActivity', 'highlightCurrentLine', 'updateAether', 'onCodeChangeMetaHandler', 'recompileIfNeeded', 'currentAutocastHandler']
       @[fat] = null
     super()