diff --git a/AUTHORS b/AUTHORS
new file mode 100644
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,17 @@
+Christopher Howard <christopher.howard@frigidcode.com>
+http://frigidcode.com
+
+Some sound effects were adapted from the following works:
+- Alien Machine Gun
+  | License: http://www.creativecommons.org/licenses/by/3.0/
+  | Recorded by Matt Cutillo
+  | soundbible.com
+- Grenade Sound
+  | License: http://www.creativecommons.org/licenses/by/3.0/
+  | Recorded by Mike Koenig
+  | soundbible.com
+- Robot Blip Sound
+  | License: http://www.creativecommons.org/licenses/by/3.0/
+  | Recorded by Marianne Gagnon
+  | soundbible.com
+
diff --git a/Display.hs b/Display.hs
--- a/Display.hs
+++ b/Display.hs
@@ -88,6 +88,7 @@
            , g (Translate (am (-400)) (ap 340)
                  (inventoryDisplay (lance r) (resourceTracker u)))
            , g (Translate (-200) 150 (levelMessage (levelMessageTimer u) (level u)))
+           , h 2.5 (i 20 (Translate (ap (220)) (am (-300)) helpColumn3))
            , h 2 (i 20 (Translate (am (-450)) (am (-230)) helpColumn2))
            , h 2 (i 20 (Translate (am (-470)) (am (-320)) helpColumn1))
            ]
@@ -143,6 +144,14 @@
         , "U-ARROW, 8 to accelerate"
         , "TAB, 5 to switch weapons"
         , "SPACEBAR, ENTER for deflector"
+        ]
+
+helpColumn3 =
+  Color white $
+    Pictures $
+      lineFormatting
+        [ "Enjoy the game? To donate"
+        , "visit <frigidcode.com/donate>."
         ]
 
 lineFormatting ys = lineFormatting' 20 0 ys
diff --git a/Resources.hs b/Resources.hs
--- a/Resources.hs
+++ b/Resources.hs
@@ -17,6 +17,7 @@
 import qualified Unit.Smart.ATank as ATank
 import qualified Unit.Smart.STank as STank
 import qualified Unit.Smart.Death as Death
+import qualified Unit.Smart.DeathII as DeathII
 import qualified Unit.Smart.Master as Master
 import qualified Unit.Smart.Ninja as Ninja
 import qualified Unit.Smart.Saucer as Saucer
@@ -33,6 +34,7 @@
                                  , "atank.bmp"
                                  , "blade.bmp"
                                  , "death.bmp"
+                                 , "deathii.bmp"
                                  , "deflector-1.bmp"
                                  , "deflector-2.bmp"
                                  , "interceptor-1.bmp"
@@ -570,6 +572,29 @@
                                       , (-280, 770)
                                       ]
                 }
+              ,
+              -- 15
+              a { asteroids = asteroidGen rt wmap
+                                [ ((-540,  -940), (-50, -40))
+                                , ((1320, -1090), (70, -100))
+                                ] ++
+                              bigAsteroidGen rt wmap
+                                [ ((900, 500), (70, 20))
+                                , ((-400, -1100), (-34, 60))
+                                ] 
+                , smartUnits = deathGen rt wmap
+                                 [ ((-600, 1300.0), 0.0)
+                                 , ((600, 1300.0), 0.0)
+                                 ] ++
+                               deathGenII rt wmap
+                                 [ ((0, -1400), 0)
+                                 ] ++
+                               masterGen rt wmap
+                                 [ ((-700, 800), 0, 10)
+                                 , ((-1000, 1000), 0, 11)
+                                 , ((1200, -1000), 0, 12)
+                                 ]
+                }
               ]
      let addItems a = do (it1, it2) <- randomItemPair
                          x1 <- randomRIO (0, 2999)
@@ -630,6 +655,9 @@
 
 deathGen rt wmap =
   map (\(x, y) -> SmartUnit (Death.new rt wmap (wrappoint wmap x) y))
+
+deathGenII rt wmap =
+  map (\(x, y) -> SmartUnit (DeathII.new rt wmap (wrappoint wmap x) y))
 
 saucerGen rt wmap =
   map (\(x, y) -> SmartUnit (Saucer.new rt wmap (wrappoint wmap x) y))
diff --git a/Step.hs b/Step.hs
--- a/Step.hs
+++ b/Step.hs
@@ -86,29 +86,37 @@
       && not (skipLevel u)
       = return (t, u)
     | level u + 1 >= length (Universe.levels u) =
-      do hPutStrLn stderr "Out of levels! Game over."
-         exitSuccess
-    | otherwise =
-  do silenceMost (arena u)
-     let a = Universe.levels u !! (level u + 1)
-     let l = lance (arena u)
-     let wmap = Universe.wrapMap a
-     let u'
-           = u { arena =
-                   a { lance =
-                         fmap
-                           (\ l ->
-                              l { Lance.center = wrappoint wmap
-                                                           (0.0, 0.0)
-                                , angle = 0.0
-                                , Lance.velocity = (0.0, 0.0)})
-                         l
-                     }
-               , level = level u + 1
-               , skipLevel = False
-               , levelMessageTimer = Just 0.0
-               }
-     return (t, u')
+      do case lance (arena u) of
+           Nothing -> return (t, u)
+           Just l -> f u { arena = (arena u) { lance = Just l
+                                                { godMode = True
+                                                , inventory =
+                                                    map (\_ -> True) (inventory l) 
+                                                , swClock = 0
+                                                } } } 0
+    | otherwise = f u (level u + 1)
+
+  where f c b = 
+          do silenceMost (arena c)
+             let a = Universe.levels c !! b
+             let l = lance (arena c)
+             let wmap = Universe.wrapMap a
+             let a'
+                   = c { arena =
+                           a { lance =
+                                 fmap
+                                   (\ l ->
+                                      l { Lance.center = wrappoint wmap
+                                                                   (0.0, 0.0)
+                                        , angle = 0.0
+                                        , Lance.velocity = (0.0, 0.0)})
+                                 l
+                             }
+                       , level = b
+                       , skipLevel = False
+                       , levelMessageTimer = Just 0.0
+                       }
+             return (t, a')
 
 {-
   Here we'll terminateAudio everything in the arena that can receive it, not
diff --git a/Unit/Smart/DeathII.hs b/Unit/Smart/DeathII.hs
new file mode 100644
--- /dev/null
+++ b/Unit/Smart/DeathII.hs
@@ -0,0 +1,226 @@
+module Unit.Smart.DeathII ( DeathII(..)
+                       , new
+                       ) where
+
+import Data.WrapAround ( WP, WM, vectorRelation )
+import Animation
+    ( Audible(..), Animation(..), termSndSrc, handSndSrc )
+import Graphics.Gloss.Data.Picture ()
+import Graphics.Gloss.Data.Color ()
+import GHC.Float ()
+import Math
+    ( vectorDirection, targetingA, subV, moreThanZero, isNan )
+import ResourceTracker ( RT, protectedGetImage )
+import Updating
+    ( Transient(..), Observant(..), InternallyUpdating(..) )
+import qualified Moving as M
+    ( Moving(..),
+      Locatable(..),
+      Colliding(..),
+      newVelocity,
+      newLocation )
+import Combat
+    ( Projectile(..), Launcher(..), Damaging(..), Damageable(..) )
+import qualified Projectile.Interceptor as P.Interceptor ( speed, new )
+import qualified Projectile.BulletMII as P.BulletMII ( new )
+import AfterEffect ( AfterEffect(AfterEffect) )
+import qualified AfterEffect.SimpleExplosion as SimpleExplosion
+    ( new )
+import Data.Maybe ()
+import Universe ( Arena(lance) )
+import qualified Universe as U ( Arena(wrapMap) )
+import Sound.ALUT ( Source )
+import Common ( Velocity, Time, Angle )
+
+
+radialVelocity = pi
+maxVelocityMag = 400
+kamikazeDamage = 150
+maxIntegrity = 16
+accelerationRate = 400
+adjAngleC = pi / 8
+shotDelay_sniper = 3.5
+shotDelay_spread = 2.5
+collisionR = 75
+
+data DeathII = DeathII { angle :: Angle
+                       , velocity :: Velocity
+                       , center :: WP
+                       , wmap :: WM
+                       , launchTube :: [Projectile]
+                       , sinceLastShot_sniper :: Time
+                       , sinceLastShot_spread :: Time
+                       , integrity :: Double
+                       , vision :: Maybe Arena
+                       , rt :: RT
+                       , queueShotSnd :: Bool
+                       , shotSndSrc :: Maybe Source
+                       }
+
+instance Audible DeathII where
+
+  processAudio s a = handSndSrc s
+                       queueShotSnd
+                       shotSndSrc
+                       (\a -> a { queueShotSnd = False })
+                       rt
+                       "energy-shot-02.wav"
+                       (\a b -> a { shotSndSrc = Just b })
+                       a (wmap s) (M.center)
+
+  terminateAudio s = termSndSrc s shotSndSrc
+
+new a b c d = DeathII { center = c
+                      , angle = d
+                      , velocity = (0, 0)
+                      , wmap = b
+                      , launchTube = []
+                      , sinceLastShot_sniper = 0
+                      , sinceLastShot_spread = 0
+                      , integrity = maxIntegrity
+                      , vision = Nothing
+                      , rt = a
+                      , queueShotSnd = False
+                      , shotSndSrc = Nothing
+                      }
+
+instance Observant DeathII where
+
+  updateVision s a = s { vision = Just a }
+
+updateAngle t s
+ = case vision s of
+     Nothing -> s
+     Just a -> case lance a of
+                Nothing -> s
+                Just l -> let b = angle s in
+                          let e = if isNan b then 0.1 else b in
+                          let m = vectorDirection
+                                       (vectorRelation
+                                         (wmap s)
+                                         (center s)
+                                         (M.center l)) in
+                          let adj
+                               | m - e > adjAngleC = radialVelocity * t
+                               | m - e < (-1) * adjAngleC = (-radialVelocity) * t
+                               | otherwise = 0 in
+                          s { angle = angle s + adj }
+
+updateVelocity t s =
+  s { velocity = b }
+  where c = M.newVelocity
+              (velocity s) accelerationRate (angle s) maxVelocityMag t
+        b = case vision s of
+              Nothing -> velocity s
+              Just a ->
+                case lance a of
+                  Nothing -> velocity s
+                  Just l -> let d = angle s in
+                            let e = if isNan d then 0.1 else d in
+                            let m = vectorDirection
+                                         (vectorRelation
+                                           (wmap s)
+                                           (center s)
+                                           (M.center l)) in
+                            if abs (m - e) <= adjAngleC then c else velocity s
+
+instance Animation DeathII where
+  image s _ = protectedGetImage (rt s) "deathii.bmp"
+
+instance M.Locatable DeathII where
+  center = center
+
+instance M.Moving DeathII where
+  velocity = velocity
+
+instance M.Colliding DeathII where
+  collisionRadius _ = collisionR
+
+instance InternallyUpdating DeathII where
+
+  preUpdate s t = (updateFiringInformation t
+                   . updateVelocity t
+                   . updateAngle t) s
+
+  postUpdate s t =
+    s { center = M.newLocation (wmap s) (center s) (velocity s) t }
+
+updateFiringInformation t s =
+  fst ((handleSpreadFiring . handleSniperFiring) (s, t))
+
+handleSniperFiring (self, t) =
+  let sinceLastShot_sniper' = sinceLastShot_sniper self + t in
+    if sinceLastShot_sniper' >= shotDelay_sniper
+      then (self { sinceLastShot_sniper = 0.0
+                , launchTube = projectile : launchTube self
+                , queueShotSnd = True
+                }, t)
+      else (self { sinceLastShot_sniper = sinceLastShot_sniper' }, t)
+  where projectile = Projectile
+                       (P.Interceptor.new
+                         (wmap self)
+                         (rt self)
+                         pAngle
+                         (center self)
+                         (velocity self))
+        pSpeed = P.Interceptor.speed
+        pAngle = case vision self of
+                   Nothing -> angle self
+                   Just arena ->
+                     case lance arena of
+                       Nothing -> angle self
+                       Just l -> targetingA
+                                   pSpeed
+                                   (vectorRelation
+                                     (U.wrapMap arena)
+                                     (center self)
+                                     (M.center l))
+                                   (subV
+                                     (M.velocity l)
+                                     (M.velocity self))
+
+handleSpreadFiring (self, t) =
+  let sinceLastShot_spread' = sinceLastShot_spread self + t in
+    if sinceLastShot_spread' >= shotDelay_spread
+      then (self { sinceLastShot_spread = 0.0
+                , launchTube = projectiles ++ launchTube self
+                , queueShotSnd = True
+                }, t)
+      else (self { sinceLastShot_spread = sinceLastShot_spread' }, t)
+  where projectiles = map projectile [ x * pi / 8.0 - pi / 4.0 | x <- [0..7] ]
+        projectile x = Projectile
+                        (P.BulletMII.new
+                          (wmap self)
+                          (pAngle + x)
+                          (center self)
+                          (velocity self))
+        pAngle = case vision self of
+                   Nothing -> angle self
+                   Just arena ->
+                     case lance arena of
+                       Nothing -> angle self
+                       Just l -> vectorDirection
+                                  (vectorRelation
+                                    (U.wrapMap arena)
+                                    (center self)
+                                    (M.center l))
+
+
+instance Launcher DeathII where
+
+  deployProjectiles s = (launchTube s, s { launchTube = [] })
+
+instance Transient DeathII where
+
+  expired' s = if moreThanZero (integrity s) then Nothing else Just [a]
+
+    where a = AfterEffect
+                (SimpleExplosion.new (rt s) (wmap s) (center s) (velocity s))
+
+instance Damageable DeathII where
+
+  inflictDamage s d = s { integrity = max 0 (integrity s - d) }
+
+instance Damaging DeathII where
+
+  damageEnergy _ = kamikazeDamage
diff --git a/edge.cabal b/edge.cabal
--- a/edge.cabal
+++ b/edge.cabal
@@ -8,7 +8,7 @@
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
 
-Version:             0.8.20
+Version:             0.9.0.1
 
 -- A short (one-line) description of the package.
 Synopsis:            Top view space combat arcade game
@@ -48,7 +48,7 @@
 
 -- Extra files to be distributed with the package, such as examples or
 -- a README.
-Extra-source-files:  DONATE
+Extra-source-files:  DONATE, edge.svg, AUTHORS
 
 -- Constraint on the version of Cabal needed to build this package.
 Cabal-version:       >=1.10
@@ -111,6 +111,7 @@
                      , Unit.Smart.ATank
                      , Unit.Smart.STank
                      , Unit.Smart.Death
+                     , Unit.Smart.DeathII
                      , Unit.Smart.Master
                      , Unit.Smart.Ninja
                      , Unit.Smart.Saucer
diff --git a/edge.svg b/edge.svg
new file mode 100644
--- /dev/null
+++ b/edge.svg
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="48"
+   height="48"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="edge.svg"
+   inkscape:export-filename="/scratch/cmhoward/haskell-edge/image/turret.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1"
+     inkscape:cx="24"
+     inkscape:cy="24"
+     inkscape:document-units="px"
+     inkscape:current-layer="svg2"
+     showgrid="false"
+     inkscape:snap-grids="true"
+     inkscape:window-width="1022"
+     inkscape:window-height="766"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2985"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="1px"
+       spacingy="1px"
+       originy="-1px"
+       originx="-1px"
+       dotted="false" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     id="layer4"
+     inkscape:label="bg"
+     style="display:inline"
+     transform="translate(0,30)"
+     sodipodi:insensitive="true">
+    <rect
+       style="fill:#000000;stroke:none"
+       id="rect3835"
+       width="48"
+       height="48"
+       x="0"
+       y="-30" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="outline" />
+  <g
+     inkscape:label="turret"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-1004.3622)"
+     sodipodi:insensitive="true">
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       d="m 29.095984,1015.3076 -5.414469,12.2301 -12.230051,-5.4145 -0.506025,1.143 12.230051,5.4145 -5.414469,12.23 1.142995,0.5061 5.414469,-12.2301 12.230051,5.4145 0.506025,-1.143 -12.230051,-5.4145 5.414469,-12.23 -1.142995,-0.5061 z"
+       id="rect3844"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g3865"
+       style="fill:#00ccff"
+       transform="matrix(1.8287927,0.80964025,-0.80964025,1.8287927,852.2889,-887.01771)">
+      <path
+         id="path3757"
+         transform="translate(0,1034.3622)"
+         d="M 7,1 7,5 C 7,3.8954305 7.8954305,3 9,3 c 1.104569,0 2,0.8954305 2,2 L 11,1 7,1 z"
+         style="fill:#00ccff;stroke:none"
+         inkscape:connector-curvature="0" />
+      <path
+         id="path3757-3"
+         d="m 7,1051.3622 0,-4 c 0,1.1046 0.89543,2 2,2 1.104569,0 2,-0.8954 2,-2 l 0,4 -4,0 z"
+         style="fill:#00ccff;stroke:none"
+         inkscape:connector-curvature="0" />
+      <path
+         transform="translate(0,1034.3622)"
+         d="M 11,9 A 2,2 0 1 1 7,9 2,2 0 1 1 11,9 z"
+         sodipodi:ry="2"
+         sodipodi:rx="2"
+         sodipodi:cy="9"
+         sodipodi:cx="9"
+         id="path2987"
+         style="fill:#00ccff;fill-opacity:1;stroke:none"
+         sodipodi:type="arc" />
+      <path
+         id="path3757-3-8-6"
+         d="m 1,1045.3622 4,0 c -1.1046,0 -2,-0.8954 -2,-2 0,-1.1046 0.8954,-2 2,-2 l -4,0 0,4 z"
+         style="fill:#00ccff;stroke:none"
+         inkscape:connector-curvature="0" />
+      <path
+         id="path3757-3-8"
+         d="m 17,1045.3622 -4,0 c 1.1046,0 2,-0.8954 2,-2 0,-1.1046 -0.8954,-2 -2,-2 l 4,0 0,4 z"
+         style="fill:#00ccff;stroke:none"
+         inkscape:connector-curvature="0" />
+    </g>
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path3891"
+       sodipodi:cx="17"
+       sodipodi:cy="17"
+       sodipodi:rx="2"
+       sodipodi:ry="2"
+       d="m 19,17 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z"
+       transform="matrix(1.3715945,0.60723019,-0.60723019,1.3715945,11.005807,994.72218)" />
+    <g
+       id="g3901"
+       style="fill:#000000"
+       transform="matrix(0.91439634,0.40482013,-0.40482013,0.91439634,427.59072,74.748853)">
+      <rect
+         transform="translate(0,1018.3622)"
+         y="2"
+         x="14"
+         height="1"
+         width="6"
+         id="rect3893"
+         style="fill:#000000;fill-opacity:1;stroke:none" />
+      <rect
+         transform="translate(0,1018.3622)"
+         y="14"
+         x="31"
+         height="6"
+         width="1"
+         id="rect3895"
+         style="fill:#000000;fill-opacity:1;stroke:none" />
+      <rect
+         transform="translate(0,1018.3622)"
+         y="31"
+         x="14"
+         height="1"
+         width="6"
+         id="rect3897"
+         style="fill:#000000;fill-opacity:1;stroke:none" />
+      <rect
+         transform="translate(0,1018.3622)"
+         y="14"
+         x="2"
+         height="6"
+         width="1"
+         id="rect3899"
+         style="fill:#000000;fill-opacity:1;stroke:none" />
+    </g>
+  </g>
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="M 3,9 3,3 9,3"
+     id="path4015"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="M 45,9 45,3 39,3"
+     id="path4015-4"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 3,39 0,6 6,0"
+     id="path4015-3"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+  <path
+     style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+     d="m 45,39 0,6 -6,0"
+     id="path4015-4-4"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccc" />
+</svg>
diff --git a/image/deathii.bmp b/image/deathii.bmp
new file mode 100644
Binary files /dev/null and b/image/deathii.bmp differ
