diff --git a/Shu-thing.cabal b/Shu-thing.cabal
--- a/Shu-thing.cabal
+++ b/Shu-thing.cabal
@@ -1,18 +1,17 @@
 name:                Shu-thing
-version:             1.0.20071203
+version:             1.1
 synopsis:            A vector shooter game
 description:         A 2-D vector graphics upwards-scrolling keyboard-controlled shooter.
-                     You shoot the enemies while dodging their bullets until you reach and defeat the enemy.
+                     You shoot the enemies while dodging their bullets until you reach and defeat the enemy boss.
 category:            Game
 license:             BSD3
 license-file:        LICENSE
 author:              Hideyuki Tanaka & Takayuki Muranushi
 maintainer:          Takayuki Muranushi <muranushi@gmail.com>, <gwern0@gmail.com>
-build-depends:       base, GLUT
+build-depends:       base, GLUT, haskell98
 build-type:          Simple
 
 executable:          shu-thing
 main-is:             Shu-thing.hs
 ghc-options:         -O2 -funbox-strict-fields -Wall -Werror -optl-Wl,-s
 ghc-prof-options:    -prof -auto-all
-extensions:          BangPatterns
diff --git a/Shu-thing.hs b/Shu-thing.hs
--- a/Shu-thing.hs
+++ b/Shu-thing.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fbang-patterns #-}
 module Main (main)
     where
 
@@ -59,7 +58,7 @@
   lookAt (Vertex3 0 0 (927 :: Double)) (Vertex3 0 0 (0 :: Double)) (Vector3 0 1 (0 :: Double))
 
 dispProc :: IORef (IO Scene) -> IO ()
-dispProc !cp = do
+dispProc cp = do
   m <- readIORef cp
   Scene next <- m
   writeIORef cp next
@@ -67,7 +66,7 @@
 data Scene = Scene (IO Scene)
 
 openingProc :: IORef [Key] -> IO Scene
-openingProc !ks = do
+openingProc ks = do
   keystate <- readIORef ks
 
   clear [ColorBuffer,DepthBuffer]
@@ -92,7 +91,7 @@
    else return $ Scene $ openingProc ks
 
 endingProc :: IORef [Key] -> IORef Double -> IO Scene
-endingProc !ks !ctr= do
+endingProc ks ctr= do
   keystate <- readIORef ks
   counter <- readIORef ctr
   modifyIORef ctr $ min 2420 . (+1.5)
@@ -152,7 +151,7 @@
      "    press x key"]
 
 mainProc :: IORef GameState -> IORef [Key] -> IO Scene
-mainProc !gs !ks = do
+mainProc gs ks = do
   keystate <- readIORef ks
   modifyIORef gs $ updateGameState keystate
   gamestate <- readIORef gs
@@ -172,7 +171,7 @@
 timerProc m = m >> addTimerCallback 16 (timerProc m)
 
 keyProc :: IORef [Key] -> Key -> KeyState -> t -> t1 -> IO ()
-keyProc keystate !key !ks _ _ =
+keyProc keystate key ks _ _ =
   case (key,ks) of
     (Char 'q',_) -> exitLoop
     (Char 'c',_) -> exitLoop
@@ -183,21 +182,21 @@
 bosstime = 6600
 bosstime2 = 7200
 
-data GameObject = Player {position :: !Point,shotEnergy :: !Double,hp :: !Double}|
-                  Bullet {position :: !Point} |
-                  EnemyMaker {timer :: !Int,deathtimer :: !Int}|
-                  Enemy {position :: !Point,hp :: !Double,anime :: !Int,enemySpec :: !EnemySpec} |
-                  Explosion {position :: !Point,hp :: !Double,size :: !Double}|
-                  EnemyBullet {position :: !Point,velocity :: !Point} |
+data GameObject = Player {position :: Point,shotEnergy :: Double,hp :: Double}|
+                  Bullet {position :: Point} |
+                  EnemyMaker {timer :: Int,deathtimer :: Int}|
+                  Enemy {position :: Point,hp :: Double,anime :: Int,enemySpec :: EnemySpec} |
+                  Explosion {position :: Point,hp :: Double,size :: Double}|
+                  EnemyBullet {position :: Point,velocity :: Point} |
                   GameoverSignal |
                   ClearSignal
                   deriving (Eq)
 
-data EnemySpec = EnemySpec {ways :: !Int,spread :: !Double,speed :: !Double,freq :: !Int,endurance :: !Double,boss :: !Bool}
+data EnemySpec = EnemySpec {ways :: Int,spread :: Double,speed :: Double,freq :: Int,endurance :: Double,boss :: Bool}
                  deriving (Eq)
 
 updateObject :: GameState -> [Key] -> GameObject -> [GameObject]
-updateObject _ !ks (!Player{position=pos,shotEnergy=sen,hp=oldhp})
+updateObject _ ks (Player{position=pos,shotEnergy=sen,hp=oldhp})
  = [(Player{position=newPos,shotEnergy=nsen,hp=newhp})] ++ shots
  where
   newPos :: Point
@@ -226,10 +225,10 @@
   shotn :: Int
   shotn = if (oldhp <= 0) then 0 else if (shotmode == 0) then 0 else
     if (sen >= 0) then 1 else 0
-updateObject _ _ (!Bullet{position=pos}) = replicate n (Bullet newpos) where
+updateObject _ _ (Bullet{position=pos}) = replicate n (Bullet newpos) where
   newpos = pos +++ (0.0,15.0)
   n = if( (\(_,y) -> y > 250) pos)then 0 else 1
-updateObject !gs _ (!EnemyMaker{timer=t,deathtimer=dtime}) =
+updateObject gs _ (EnemyMaker{timer=t,deathtimer=dtime}) =
  [EnemyMaker{timer=t+1,deathtimer=newdtime}] ++ enemies ++ deatheffects where
   enemies = replicate n $ Enemy{position = (320*sin(dt*dt),240),hp=1.0,anime=0,enemySpec = spec}
   dt :: Double
@@ -266,20 +265,21 @@
     ] ++
      map (\o -> EnemySpec {ways=o,spread=0.1,speed=4.0,freq=20,endurance=3.0,boss=False}) [0,1 ..]
 
-updateObject !gs _ !oldenemy@(Enemy{position=pos,hp=oldhp,anime=oldanime,enemySpec=spec})  =
+updateObject gs _ oldenemy@(Enemy{position=pos,hp=oldhp,anime=oldanime,enemySpec=spec})  =
   replicate n (oldenemy{position=newpos,hp=newhp,anime=newanime,enemySpec=newspec})
    ++ shots ++ explosions where
     newpos = if isBoss then (200 * sin(danime/100),200 + 40 * cos(danime/80))
       else pos +++ (0.0,-1.0)
     newhp = oldhp
     newanime = oldanime + 1
-    newspec = if(not isBoss) then spec else
-     if (oldhp>0.75) then EnemySpec{ways=0,spread=0.1,speed=5.0,freq=10,endurance=300.0,boss=True} else
-      if (oldhp>0.50) then EnemySpec{ways=8,spread=0.15,speed=3.0,freq=30,endurance=300.0,boss=True} else
-       if (oldhp>0.25) then EnemySpec{ways=2,spread=1.2,speed=15.0,freq=10,endurance=300.0,boss=True} else
-        if (oldhp>0.05) then EnemySpec{ways=40,spread=0.075,speed=3.0,freq=60,endurance=400.0,boss=True} else
-         if (oldhp>0.00) then EnemySpec{ways=15,spread=0.2,speed=16.0,freq=20,endurance=900.0,boss=True} else
-          EnemySpec{ways=(-1),spread=0.1,speed=3.0,freq=10,endurance=300.0,boss=True}
+    newspec
+        | (not isBoss) = spec
+        | (oldhp > 0.75) = EnemySpec{ways=0,spread=0.1,speed=5.0,freq=10,endurance=300.0,boss=True}
+        | (oldhp > 0.50) = EnemySpec{ways=8,spread=0.15,speed=3.0,freq=30,endurance=300.0,boss=True}
+        | (oldhp > 0.25) = EnemySpec{ways=2,spread=1.2,speed=15.0,freq=10,endurance=300.0,boss=True}
+        | (oldhp > 0.05) = EnemySpec{ways=40,spread=0.075,speed=3.0,freq=60,endurance=400.0,boss=True}
+        | (oldhp > 0.00) = EnemySpec{ways=15,spread=0.2,speed=16.0,freq=20,endurance=900.0,boss=True}
+        | otherwise = EnemySpec{ways=(-1),spread=0.1,speed=3.0,freq=10,endurance=300.0,boss=True}
     danime :: Double
     danime = fromIntegral oldanime
     explosions = if(oldhp<=0 && not isBoss) then [Explosion{position=pos,hp=1.0,size=1.0}] else []
@@ -299,9 +299,9 @@
     frq = freq spec
     sprd= spread spec
     isBoss = boss spec
-updateObject _ _ !e@(Explosion{}) = if(hp e>0) then [e{hp=hp e - (0.024/(size e))}] else []
-updateObject _ _ !eb@(EnemyBullet{}) = if(outofmap (position eb)) then [] else
-  [eb{position=position eb+++velocity eb}]
+updateObject _ _ e@(Explosion{}) = if(hp e>0) then [e{hp=hp e - (0.024/(size e))}] else []
+updateObject _ _ eb@(EnemyBullet{}) = if(outofmap (position eb)) then [] else
+  [eb{position=position eb +++ velocity eb}]
 updateObject _ _ go = [go]
 
 watcher :: [GameObject] -> [GameObject]
@@ -334,7 +334,7 @@
                            _             -> (e,b,eb,p,o:x)
 
 renderGameObject :: GameObject -> IO ()
-renderGameObject !Player{position=pos,hp=h} = preservingMatrix $ do
+renderGameObject Player{position=pos,hp=h} = preservingMatrix $ do
   let (x,y) = pos
   color (Color3 (1.0 :: Double) h h)
   translate (Vector3 x y 0)
@@ -342,7 +342,7 @@
   rotate (x) (Vector3 0 1 0)
   rotate (30 :: Double) (Vector3 0 0 1)
   renderObject Wireframe Dodecahedron
-renderGameObject !Bullet{position=pos} = preservingMatrix $ do
+renderGameObject Bullet{position=pos} = preservingMatrix $ do
   let (x,y) = pos
   color (Color3 (0.6 :: Double) 0.6 1.0)
   translate (Vector3 x y 0)
@@ -350,7 +350,7 @@
   rotate (45 :: Double) (Vector3 0 1 0)
   rotate (90 :: Double) (Vector3 1 0 0)
   renderObject Wireframe Tetrahedron
-renderGameObject !Enemy{position=pos,anime=a,hp=h,enemySpec=EnemySpec{boss=False}} = preservingMatrix $ do
+renderGameObject Enemy{position=pos,anime=a,hp=h,enemySpec=EnemySpec{boss=False}} = preservingMatrix $ do
   let (x,y) = pos
   color (Color3 (cos rho) (sin rho) (0.0 :: Double))
   translate (Vector3 x y 0)
@@ -359,7 +359,7 @@
   renderObject Wireframe Octahedron where
     theta = fromIntegral a
     rho = h * 3.14 / 2
-renderGameObject !Enemy{position=pos,anime=a,hp=h,enemySpec=EnemySpec{boss=True}} = preservingMatrix $ do
+renderGameObject Enemy{position=pos,anime=a,hp=h,enemySpec=EnemySpec{boss=True}} = preservingMatrix $ do
   let (x,y) = pos
   color (Color3 (cos rho) (sin rho) (0.0 :: Double))
   translate (Vector3 x y 0)
@@ -368,7 +368,7 @@
   renderObject Wireframe (Teapot 1.0) where
     theta = fromIntegral a
     rho = h * 3.14 / 2
-renderGameObject !Explosion{position=pos,hp=h,size=s}= preservingMatrix $ do
+renderGameObject Explosion{position=pos,hp=h,size=s}= preservingMatrix $ do
   let (x,y) = pos
   color (Color3 h 0.0 0.0)
   translate (Vector3 x y 0)
@@ -377,7 +377,7 @@
   scale r r r
   renderObject Wireframe Icosahedron where
     r = s*(100 - h*h*80)
-renderGameObject !EnemyBullet{position=pos} = preservingMatrix $ do
+renderGameObject EnemyBullet{position=pos} = preservingMatrix $ do
   let (x,y) = pos
   color (Color3 (1.0 :: Double) 1.0 1.0)
   translate (Vector3 x y 0)
@@ -393,16 +393,16 @@
   [(Player{position=(0.0,0.0),shotEnergy=0.0,hp=1.0}),(EnemyMaker{timer=0,deathtimer=0})]}
 
 renderGameState :: GameState -> IO ()
-renderGameState !GameState{objects=os} = mapM_ renderGameObject os
+renderGameState GameState{objects=os} = mapM_ renderGameObject os
 
 updateGameState :: [Key] -> GameState -> GameState
-updateGameState !ks !gs@(GameState { objects=os }) = newgs where
+updateGameState ks gs@(GameState { objects=os }) = newgs where
   newgs = GameState{objects = watcher $ concatMap (updateObject gs ks) os}
 
 playerpos :: GameState -> Point
 playerpos = position . findplayer
 findplayer :: GameState -> GameObject
-findplayer !GameState{objects=os} = player where
+findplayer GameState{objects=os} = player where
   [player] = filter (\o -> case o of
     Player{} -> True
     _        -> False) os
@@ -425,20 +425,20 @@
 (ax,ay) +++ (bx,by) = (ax+bx, ay+by)
 
 (-+-) :: (Num t1, Num t) => (t, t1) -> (t, t1) -> (t, t1)
-(!ax,!ay) -+- (!bx,!by) = (ax-bx,ay-by)
+(ax,ay) -+- (bx,by) = (ax-bx,ay-by)
 
 (*++) ::  (Num t) => (t, t) -> t -> (t, t)
-(!ax,!ay) *++ (!s) = (ax*s,ay*s)
+(ax,ay) *++ (s) = (ax*s,ay*s)
 
 (***) :: (Num t) => (t, t) -> (t, t) -> (t, t)
-(!ax,!ay) *** (!bx,!by) = (ax*bx-ay*by,ay*bx+ax*by)
+(ax,ay) *** (bx,by) = (ax*bx-ay*by,ay*bx+ax*by)
 
 sq :: Double -> Double
-sq !x = x*x
+sq x = x*x
 
 distance, distance2 :: Point -> Point -> Double
 distance a b= sqrt $ distance2 a b
-distance2 !(ax,ay) !(bx,by) = sq(ax-bx) + sq(ay-by)
+distance2 (ax,ay) (bx,by) = sq(ax-bx) + sq(ay-by)
 
 outofmap :: Point -> Bool
-outofmap !(x,y) = (not $ abs x < 320) || (not $ abs y < 240)
+outofmap (x,y) = (not $ abs x < 320) || (not $ abs y < 240)
