diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee
index 4c61a7766..9b6b68804 100644
--- a/app/lib/surface/CocoSprite.coffee
+++ b/app/lib/surface/CocoSprite.coffee
@@ -76,6 +76,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
     @stillLoading = false
     @actions = @thangType.getActions()
     @buildFromSpriteSheet @buildSpriteSheet()
+    @createMarks()
 
   destroy: ->
     mark.destroy() for name, mark of @marks
@@ -411,12 +412,34 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
       pos.y *= @thang.scaleFactorY ? scaleFactor
     pos
 
+  createMarks: ->
+    if @thang
+      allProps = []
+      allProps = allProps.concat (@thang.hudProperties ? [])
+      allProps = allProps.concat (@thang.programmableProperties ? [])
+      allProps = allProps.concat (@thang.moreProgrammableProperties ? [])
+
+      @addMark('voiceradius') if 'voiceRange' in allProps
+      @addMark('visualradius') if 'visualRange' in allProps
+      @addMark('attackradius') if 'attackRange' in allProps
+
+      @addMark('bounds').toggle true if @thang?.drawsBounds
+      @addMark('shadow').toggle true unless @thangType.get('shadow') is 0
+
   updateMarks: ->
     return unless @options.camera
     @addMark 'repair', null, 'repair' if @thang?.errorsOut
     @marks.repair?.toggle @thang?.errorsOut
-    @addMark('bounds').toggle true if @thang?.drawsBounds
-    @addMark('shadow').toggle true unless @thangType.get('shadow') is 0
+
+    if @selected
+      @marks.voiceradius?.toggle true 
+      @marks.visualradius?.toggle true 
+      @marks.attackradius?.toggle true 
+    else
+      @marks.voiceradius?.toggle false
+      @marks.visualradius?.toggle false
+      @marks.attackradius?.toggle false
+
     mark.update() for name, mark of @marks
     #@thang.effectNames = ['berserk', 'confuse', 'control', 'curse', 'fear', 'poison', 'paralyze', 'regen', 'sleep', 'slow', 'haste']
     @updateEffectMarks() if @thang?.effectNames?.length or @previousEffectNames?.length
diff --git a/app/lib/surface/Mark.coffee b/app/lib/surface/Mark.coffee
index 07536aef5..dc7568b12 100644
--- a/app/lib/surface/Mark.coffee
+++ b/app/lib/surface/Mark.coffee
@@ -55,6 +55,9 @@ module.exports = class Mark extends CocoClass
       if @name is 'bounds' then @buildBounds()
       else if @name is 'shadow' then @buildShadow()
       else if @name is 'debug' then @buildDebug()
+      else if @name is 'voiceradius' then @buildRadius('voice')
+      else if @name is 'visualradius' then @buildRadius('visual')
+      else if @name is 'attackradius' then @buildRadius('attack')
       else if @thangType then @buildSprite()
       else console.error "Don't know how to build mark for", @name
       @mark?.mouseEnabled = false
@@ -114,8 +117,59 @@ module.exports = class Mark extends CocoClass
     @mark.layerIndex = 10
     #@mark.cache 0, 0, diameter, diameter  # not actually faster than simple ellipse draw
 
-  buildRadius: ->
-    return  # not implemented
+  buildRadius: (type) ->
+    return if type is 'voice' and @sprite.thang.voiceRange > 9000
+    return if type is 'visual' and @sprite.thang.visualRange > 9000
+    return if type is 'attack' and @sprite.thang.attackRange > 9000
+
+    colors =
+      voice: "rgba(0, 145, 0, alpha)"
+      visual: "rgba(0, 0, 145, alpha)"
+      attack: "rgba(145, 0, 0, alpha)"
+
+    color = colors[type]
+
+    @mark = new createjs.Shape()
+    @mark.graphics.beginFill color.replace('alpha', 0.4)
+    
+    if type is 'voice'
+      r = @sprite.thang.voiceRange
+      ranges = [
+        r, 
+        if 'visualradius' of @sprite.marks and @sprite.thang.visualRange < 9001 then @sprite.thang.visualRange else 0,
+        if 'attackradius' of @sprite.marks and @sprite.thang.attackRange < 9001 then @sprite.thang.attackRange else 0 
+      ]
+    else if type is 'visual'
+      r = @sprite.thang.visualRange
+      ranges = [
+        r, 
+        if 'attackradius' of @sprite.marks and @sprite.thang.attackRange < 9001 then @sprite.thang.attackRange else 0,
+        if 'voiceradius' of @sprite.marks and @sprite.thang.voiceRange < 9001 then @sprite.thang.voiceRange else 0, 
+      ]
+    else if type is 'attack'
+      r = @sprite.thang.attackRange
+      ranges = [
+        r, 
+        if 'voiceradius' of @sprite.marks and @sprite.thang.voiceRange < 9001 then @sprite.thang.voiceRange else 0, 
+        if 'visualradius' of @sprite.marks and @sprite.thang.visualRange < 9001 then @sprite.thang.visualRange else 0
+      ]
+      
+    # Draw the outer circle
+    @mark.graphics.drawCircle 0, 0, r * Camera.PPM
+
+    # Cut out the inner circle
+    if Math.max(ranges['1'], ranges['2']) < r
+      @mark.graphics.arc 0, 0, Math.max(ranges['1'], ranges['2']) * Camera.PPM, Math.PI*2, 0, true
+    else if Math.min(ranges['1'], ranges['2']) < r
+      @mark.graphics.arc 0, 0, Math.min(ranges['1'], ranges['2']) * Camera.PPM, Math.PI*2, 0, true
+
+    # Add perspective
+    @mark.scaleY *= @camera.y2x
+
+    @mark.graphics.endStroke()
+    @mark.graphics.endFill()
+
+    return
 
   buildDebug: ->
     @mark = new createjs.Shape()