diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,22 +1,22 @@
-0.2.5 - 140928
-* fixed compilation with GLFW-0.5.2.*
-
-0.2.4 - 111122
-* adjusted for version 2.5.0 of the library
-* moved random number generator into the example
-
-0.2.3 - 110402
-* adjusted for version 2.2.0 of the library
-
-0.2.2 - 101203
-* removed mtl dependency (which also fixed a crash)
-
-0.2.1 - 100718
-* adjusted for version 2 of the library
-
-0.2.0 - 100424
-* sanitised enemy movement
-* added enter as an alternative fire key
-
-0.1.0 - 100211
-* first public version
+0.2.5 - 140928
+* fixed compilation with GLFW-0.5.2.*
+
+0.2.4 - 111122
+* adjusted for version 2.5.0 of the library
+* moved random number generator into the example
+
+0.2.3 - 110402
+* adjusted for version 2.2.0 of the library
+
+0.2.2 - 101203
+* removed mtl dependency (which also fixed a crash)
+
+0.2.1 - 100718
+* adjusted for version 2 of the library
+
+0.2.0 - 100424
+* sanitised enemy movement
+* added enter as an alternative fire key
+
+0.1.0 - 100211
+* first public version
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,28 +1,28 @@
-Copyright (c) 2010, Patai Gergely
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-3. Neither the name of the author nor the names of its contributors may be
-   used to endorse or promote products derived from this software without
-   specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2010, Patai Gergely
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of its contributors may be
+   used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/README b/README
--- a/README
+++ b/README
@@ -1,12 +1,12 @@
-Dungeons of Wor
-===============
-
-Dungeons of Wor is a homage to the classic arcade game, Wizard of Wor.
-It uses the artwork and levels from the arcade version, but the
-gameplay mechanics differ from the original in several ways.
-
-Controls:
-
-  player one and menu - arrows + right control/enter
-  player two          - WASD + left control
-  quit at any time    - escape
+Dungeons of Wor
+===============
+
+Dungeons of Wor is a homage to the classic arcade game, Wizard of Wor.
+It uses the artwork and levels from the arcade version, but the
+gameplay mechanics differ from the original in several ways.
+
+Controls:
+
+  player one and menu - arrows + right control/enter
+  player two          - WASD + left control
+  quit at any time    - escape
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,3 +1,3 @@
-import Distribution.Simple
-
-main = defaultMain
+import Distribution.Simple
+
+main = defaultMain
diff --git a/data/charset.txt b/data/charset.txt
--- a/data/charset.txt
+++ b/data/charset.txt
@@ -1,443 +1,443 @@
- 
-........
-........
-........
-........
-........
-........
-........
-........
-........
-........
-
-A
-...##...
-..####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.######.
-.######.
-.##..##.
-.##..##.
-
-B
-.#####..
-.######.
-.##..##.
-.##..##.
-.#####..
-.######.
-.##..##.
-.##..##.
-.######.
-.#####..
-
-C
-..####..
-.######.
-.##..##.
-.##.....
-.##.....
-.##.....
-.##.....
-.##..##.
-.######.
-..####..
-
-D
-.#####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-.#####..
-
-E
-.######.
-.######.
-.##.....
-.##.....
-.#####..
-.#####..
-.##.....
-.##.....
-.######.
-.######.
-
-F
-.######.
-.######.
-.##.....
-.##.....
-.#####..
-.#####..
-.##.....
-.##.....
-.##.....
-.##.....
-
-G
-..####..
-.######.
-.##.....
-.##.....
-.##.....
-.##.###.
-.##.###.
-.##..##.
-.######.
-..####..
-
-H
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-
-I
-..####..
-..####..
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-..####..
-..####..
-
-J
-.....##.
-.....##.
-.....##.
-.....##.
-.....##.
-.....##.
-.##..##.
-.##..##.
-.######.
-..####..
-
-K
-.##..##.
-.##..##.
-.##.###.
-.#####..
-.####...
-.####...
-.##.##..
-.##.###.
-.##..##.
-.##..##.
-
-L
-.##.....
-.##.....
-.##.....
-.##.....
-.##.....
-.##.....
-.##.....
-.##.....
-.######.
-.######.
-
-M
-##....##
-###..###
-###..###
-##.##.##
-##.##.##
-##....##
-##....##
-##....##
-##....##
-##....##
-
-N
-.##..##.
-.##..##.
-.###.##.
-.######.
-.######.
-.##.###.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-
-O
-..####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-..####..
-
-P
-.#####..
-.######.
-.##..##.
-.##..##.
-.######.
-.#####..
-.##.....
-.##.....
-.##.....
-.##.....
-
-Q
-..####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##.###.
-.##..#..
-..###.#.
-
-R
-.#####..
-.######.
-.##..##.
-.##..##.
-.######.
-.#####..
-.##.###.
-.##..##.
-.##..##.
-.##..##.
-
-S
-..####..
-.######.
-.##..##.
-.##.....
-.#####..
-..#####.
-.....##.
-.##..##.
-.######.
-..####..
-
-T
-.######.
-.######.
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-
-U
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-..####..
-
-V
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-..####..
-..####..
-...##...
-...##...
-
-W
-##....##
-##....##
-##....##
-##.##.##
-##.##.##
-##.##.##
-########
-###..###
-##....##
-##....##
-
-X
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-..####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-
-Y
-.##..##.
-.##..##.
-.######.
-..####..
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-
-Z
-.######.
-.######.
-.....##.
-....###.
-...###..
-..###...
-.###....
-.##.....
-.######.
-.######.
-
-0
-..####..
-.######.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-..####..
-
-1
-...##...
-..###...
-...##...
-...##...
-...##...
-...##...
-...##...
-...##...
-..####..
-..####..
-
-2
-..####..
-.######.
-.##..##.
-.....##.
-..#####.
-.#####..
-.##.....
-.##.....
-.######.
-.######.
-
-3
-..####..
-.######.
-.##..##.
-.....##.
-...###..
-...####.
-.....##.
-.##..##.
-.######.
-..####..
-
-4
-.##..##.
-.##..##.
-.##..##.
-.##..##.
-.######.
-.######.
-.....##.
-.....##.
-.....##.
-.....##.
-
-5
-.#####..
-.#####..
-.##.....
-.##.....
-.#####..
-.######.
-.....##.
-.##..##.
-.######.
-..####..
-
-6
-..####..
-.#####..
-.##.....
-.##.....
-.#####..
-.######.
-.##..##.
-.##..##.
-.######.
-..####..
-
-7
-.######.
-.######.
-.....##.
-....###.
-....##..
-...###..
-...##...
-..###...
-..##....
-..##....
-
-8
-..####..
-.######.
-.##..##.
-.##..##.
-..####..
-.######.
-.##..##.
-.##..##.
-.######.
-..####..
-
-9
-..####..
-.######.
-.##..##.
-.##..##.
-.######.
-..#####.
-.....##.
-.....##.
-..#####.
-..####..
+ 
+........
+........
+........
+........
+........
+........
+........
+........
+........
+........
+
+A
+...##...
+..####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.######.
+.######.
+.##..##.
+.##..##.
+
+B
+.#####..
+.######.
+.##..##.
+.##..##.
+.#####..
+.######.
+.##..##.
+.##..##.
+.######.
+.#####..
+
+C
+..####..
+.######.
+.##..##.
+.##.....
+.##.....
+.##.....
+.##.....
+.##..##.
+.######.
+..####..
+
+D
+.#####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+.#####..
+
+E
+.######.
+.######.
+.##.....
+.##.....
+.#####..
+.#####..
+.##.....
+.##.....
+.######.
+.######.
+
+F
+.######.
+.######.
+.##.....
+.##.....
+.#####..
+.#####..
+.##.....
+.##.....
+.##.....
+.##.....
+
+G
+..####..
+.######.
+.##.....
+.##.....
+.##.....
+.##.###.
+.##.###.
+.##..##.
+.######.
+..####..
+
+H
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+
+I
+..####..
+..####..
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+..####..
+..####..
+
+J
+.....##.
+.....##.
+.....##.
+.....##.
+.....##.
+.....##.
+.##..##.
+.##..##.
+.######.
+..####..
+
+K
+.##..##.
+.##..##.
+.##.###.
+.#####..
+.####...
+.####...
+.##.##..
+.##.###.
+.##..##.
+.##..##.
+
+L
+.##.....
+.##.....
+.##.....
+.##.....
+.##.....
+.##.....
+.##.....
+.##.....
+.######.
+.######.
+
+M
+##....##
+###..###
+###..###
+##.##.##
+##.##.##
+##....##
+##....##
+##....##
+##....##
+##....##
+
+N
+.##..##.
+.##..##.
+.###.##.
+.######.
+.######.
+.##.###.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+
+O
+..####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+..####..
+
+P
+.#####..
+.######.
+.##..##.
+.##..##.
+.######.
+.#####..
+.##.....
+.##.....
+.##.....
+.##.....
+
+Q
+..####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##.###.
+.##..#..
+..###.#.
+
+R
+.#####..
+.######.
+.##..##.
+.##..##.
+.######.
+.#####..
+.##.###.
+.##..##.
+.##..##.
+.##..##.
+
+S
+..####..
+.######.
+.##..##.
+.##.....
+.#####..
+..#####.
+.....##.
+.##..##.
+.######.
+..####..
+
+T
+.######.
+.######.
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+
+U
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+..####..
+
+V
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+..####..
+..####..
+...##...
+...##...
+
+W
+##....##
+##....##
+##....##
+##.##.##
+##.##.##
+##.##.##
+########
+###..###
+##....##
+##....##
+
+X
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+..####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+
+Y
+.##..##.
+.##..##.
+.######.
+..####..
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+
+Z
+.######.
+.######.
+.....##.
+....###.
+...###..
+..###...
+.###....
+.##.....
+.######.
+.######.
+
+0
+..####..
+.######.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+..####..
+
+1
+...##...
+..###...
+...##...
+...##...
+...##...
+...##...
+...##...
+...##...
+..####..
+..####..
+
+2
+..####..
+.######.
+.##..##.
+.....##.
+..#####.
+.#####..
+.##.....
+.##.....
+.######.
+.######.
+
+3
+..####..
+.######.
+.##..##.
+.....##.
+...###..
+...####.
+.....##.
+.##..##.
+.######.
+..####..
+
+4
+.##..##.
+.##..##.
+.##..##.
+.##..##.
+.######.
+.######.
+.....##.
+.....##.
+.....##.
+.....##.
+
+5
+.#####..
+.#####..
+.##.....
+.##.....
+.#####..
+.######.
+.....##.
+.##..##.
+.######.
+..####..
+
+6
+..####..
+.#####..
+.##.....
+.##.....
+.#####..
+.######.
+.##..##.
+.##..##.
+.######.
+..####..
+
+7
+.######.
+.######.
+.....##.
+....###.
+....##..
+...###..
+...##...
+..###...
+..##....
+..##....
+
+8
+..####..
+.######.
+.##..##.
+.##..##.
+..####..
+.######.
+.##..##.
+.##..##.
+.######.
+..####..
+
+9
+..####..
+.######.
+.##..##.
+.##..##.
+.######.
+..#####.
+.....##.
+.....##.
+..#####.
+..####..
diff --git a/data/levels.txt b/data/levels.txt
--- a/data/levels.txt
+++ b/data/levels.txt
@@ -1,329 +1,329 @@
-"arena"
-+---------------------+
-|                     |
-| +-+ +---+ +---+ +-+ |
-|     |         |     |
-+ +---+         +---+ +
-<                     >
-+ +-+             +-+ +
-|   |             |   |
-| + +-+ +-----+ +-+ + |
-| |                 | |
-| + +   + +-+ +   + + |
-|   |   |     |   |   |
-+*+-+---+-----+---+-+*+
-
-"pit"
-+---------------------+
-|                     |
-|                     |
-|                     |
-+                     +
-<                     >
-+                     +
-|                     |
-|                     |
-|                     |
-|                     |
-|                     |
-+*+-----------------+*+
-
-"b1"
-+-----+---------+-----+
-|     |         |     |
-| +-+ + +-+ +-+ + +-+ |
-| |                 | |
-+ + + +---+ +---+ + + +
-<   |     | |     |   >
-+   | +-+ + + +-+ |   +
-|   | |         | |   |
-| +-+ + +-+ +-+ + +-+ |
-| |       | |       | |
-| + +-+ + + + + +-+ + |
-|       |     |       |
-+*+-----+-----+-----+*+
-
-"b2"
-+---------------------+
-|                     |
-| + + + + + + + + + + |
-| | | | | | | | | | | |
-+ + + | + | | + | + + +
-<     |   | |   |     >
-+-+ + +-+ + + +-+ + +-+
-|   |             |   |
-| + +-+   + +   +-+ + |
-| |   |   | |   |   | |
-| + + + +-+ +-+ + + + |
-|   |             |   |
-+*+-+-------------+-+*+
-
-"b3"
-+---+-------------+---+
-|   |             |   |
-| + + +-+ +-+ +-+ + + |
-| |   |         |   | |
-+ + + | +-+ +-+ | + + +
-<   | |   | |   | |   >
-+---+ +-+ | | +-+ +---+
-|         | |         |
-| + +---+ + + +---+ + |
-| |                 | |
-| + +   + +-+ +   + + |
-|   |   |     |   |   |
-+*+-+---+-----+---+-+*+
-
-"b4"
-+-------+-----+-------+
-|       |     |       |
-| +---+ + + + + +---+ |
-| |       | |       | |
-+ + +---+ + + +---+ + +
-<   |             |   >
-+-+ | + +-+ +-+ + | +-+
-|   | |         | |   |
-| + + + +-----+ + + + |
-| |                 | |
-| +   + +-+ +-+ +   + |
-|     |         |     |
-+*+---+---------+---+*+
-
-"b5"
-+-----+---------+-----+
-|     |         |     |
-| +-+ + +-+ +-+ + +-+ |
-|         | |         |
-+ +---+ + + + + +---+ +
-<       |     |       >
-+-+ +-+ + + + + +-+ +-+
-|     |   | |   |     |
-| +-+ | +-+ +-+ | +-+ |
-|     |         |     |
-| +-+ + + +-+ + + +-+ |
-|       |     |       |
-+*+-----+-----+-----+*+
-
-"b6"
-+---+-------------+---+
-|   |             |   |
-| + + +-+ +-+ +-+ + + |
-| |                 | |
-+ + + +-+ +-+ +-+ + + +
-<   |   |     |   |   >
-+-+ |   +-+ +-+   | +-+
-|   |   |     |   |   |
-| + +-+ + +-+ + +-+ + |
-| |                 | |
-| +   + +-+ +-+ +   + |
-|     |         |     |
-+*+---+---------+---+*+
-
-"b7"
-+-----+---------+-----+
-|     |         |     |
-| +-+ + +-+ +-+ + +-+ |
-| |                 | |
-+ + +-+ +-+ +-+ +-+ + +
-<   |     | |     |   >
-+-+ + + + | | + + + +-+
-|     | | | | | |     |
-| +-+ + | + + | + +-+ |
-|       |     |       |
-| +-+ +-+ + + +-+ +-+ |
-|         | |         |
-+*+-------+-+-------+*+
-
-"b8"
-+---------------------+
-|                     |
-| +-+   +-+ +-+   +-+ |
-| |     |     |     | |
-+ + +-+ + +-+ + +-+ + +
-<   |             |   >
-+-+ + + + +-+ + + + +-+
-|     | |     | |     |
-| +-+ | +-+ +-+ | +-+ |
-|     |         |     |
-| +-+ + + +-+ + + +-+ |
-|       |     |       |
-+*+-----+-----+-----+*+
-
-"b9"
-+---------------------+
-|                     |
-| +---+ + +-+ + +---+ |
-|       |     |       |
-+ +-+ +-+ +-+ +-+ +-+ +
-<     |         |     >
-+-+ + + +-+ +-+ + + +-+
-|   |   |     |   |   |
-| +-+ + + + + + + +-+ |
-| |   |   | |   |   | |
-| + +-+ + + + + +-+ + |
-|       |     |       |
-+*+-----+-----+-----+*+
-
-"b10"
-+-----+---------+-----+
-|     |         |     |
-| +-+ + +-+ +-+ + +-+ |
-|       |     |       |
-+ +---+ + +-+ + +---+ +
-<                     >
-+-+ + + + + + + + + +-+
-|   | | | | | | | |   |
-| +-+ + | + + | + +-+ |
-|       |     |       |
-| +-+ + +-+ +-+ + +-+ |
-|     |         |     |
-+*+---+---------+---+*+
-
-"b11"
-+-----+---------+-----+
-|     |         |     |
-| +-+ | + +-+ + | +-+ |
-|     | |     | |     |
-+ +-+ + +-+ +-+ + +-+ +
-<   |             |   >
-+-+ + + + +-+ + + + +-+
-|     | |     | |     |
-| +---+ + +-+ + +---+ |
-|                     |
-| +-+   + +-+ +   +-+ |
-|       |     |       |
-+*+-----+-----+-----+*+
-
-"b12"
-+---+-------------+---+
-|   |             |   |
-| + + +-+ +-+ +-+ + + |
-| |   |         |   | |
-+ + +-+ + +-+ + +-+ + +
-<       |     |       >
-+-+ + + | +-+ | + + +-+
-|   | | |     | | |   |
-| + | + + + + + + | + |
-| | |     | |     | | |
-| + + + +-+ +-+ + + + |
-|     |         |     |
-+*+---+---------+---+*+
-
-"w1"
-+---------------------+
-|                     |
-| +     +     +     + |
-| |     |     |     | |
-+ +-+ +-+ + + +-+ +-+ +
-<   |     | |     |   >
-+   + +   | |   + +   +
-|     |   | |   |     |
-| +-+ +-+ + + +-+ +-+ |
-| |     |     |     | |
-| +     +     +     + |
-|                     |
-+*+-----------------+*+
-
-"w2"
-+---------------------+
-|                     |
-|       +-+ +-+       |
-|       |     |       |
-+     +-+     +-+     +
-<     |         |     >
-+   +-+   + +   +-+   +
-|   |     | |     |   |
-| +-+   +-+ +-+   +-+ |
-|       |     |       |
-|     +-+     +-+     |
-|                     |
-+*+-----------------+*+
-
-"w3"
-+---------------------+
-|                     |
-|   +   +-+ +-+   +   |
-|   |     | |     |   |
-+ +-+-+ + + + + +-+-+ +
-<   |   |     |   |   >
-+ + + +-+-+ +-+-+ + + +
-| |     |     |     | |
-| +-+   +     +   +-+ |
-|   |             |   |
-|   +---+     +---+   |
-|                     |
-+*+-----------------+*+
-
-"w4"
-+---------------------+
-|                     |
-| +   + +     + +   + |
-| |   | |     | |   | |
-+ | + + | + + | + + | +
-< | |   | | | |   | | >
-+ + | + + | | + + | + +
-|   | |   | |   | |   |
-|   + | + + + + | +   |
-|     | |     | |     |
-|     + +     + +     |
-|                     |
-+*+-----------------+*+
-
-"w5"
-+---------------------+
-|                     |
-| +-+     + +     +-+ |
-|   |     | |     |   |
-+   | +---+ +---+ |   +
-<   | |         | |   >
-+ +-+ + +     + + +-+ +
-|       |     |       |
-|   +---+     +---+   |
-|   |             |   |
-|   +             +   |
-|                     |
-+*+-----------------+*+
-
-"w6"
-+---------------------+
-|                     |
-| +-+   + +-+ +   +-+ |
-|       |     |       |
-+ + +-+ + +-+ + +-+ + +
-< |                 | >
-+ |   +-+     +-+   | +
-| |                 | |
-| + +-+ + +-+ + +-+ + |
-|       |     |       |
-| +-+   + +-+ +   +-+ |
-|                     |
-+*+-----------------+*+
-
-"w7"
-+---------------------+
-|                     |
-| +-+     + +     +-+ |
-|   |     | |     |   |
-+   +-+ +-+ +-+ +-+   +
-<     | |     | |     >
-+     | |     | |     +
-|     | |     | |     |
-|   +-+ +-+ +-+ +-+   |
-|   |     | |     |   |
-| +-+     + +     +-+ |
-|                     |
-+*+-----------------+*+
-
-"w8"
-+---------------------+
-|                     |
-| +-+   +-+ +-+   +-+ |
-|   |             |   |
-+   +-+   +-+   +-+   +
-<     |         |     >
-+     +-+     +-+     +
-|       |     |       |
-|   +   +-+ +-+   +   |
-|   |     | |     |   |
-|   +     + +     +   |
-|                     |
-+*+-----------------+*+
+"arena"
++---------------------+
+|                     |
+| +-+ +---+ +---+ +-+ |
+|     |         |     |
++ +---+         +---+ +
+<                     >
++ +-+             +-+ +
+|   |             |   |
+| + +-+ +-----+ +-+ + |
+| |                 | |
+| + +   + +-+ +   + + |
+|   |   |     |   |   |
++*+-+---+-----+---+-+*+
+
+"pit"
++---------------------+
+|                     |
+|                     |
+|                     |
++                     +
+<                     >
++                     +
+|                     |
+|                     |
+|                     |
+|                     |
+|                     |
++*+-----------------+*+
+
+"b1"
++-----+---------+-----+
+|     |         |     |
+| +-+ + +-+ +-+ + +-+ |
+| |                 | |
++ + + +---+ +---+ + + +
+<   |     | |     |   >
++   | +-+ + + +-+ |   +
+|   | |         | |   |
+| +-+ + +-+ +-+ + +-+ |
+| |       | |       | |
+| + +-+ + + + + +-+ + |
+|       |     |       |
++*+-----+-----+-----+*+
+
+"b2"
++---------------------+
+|                     |
+| + + + + + + + + + + |
+| | | | | | | | | | | |
++ + + | + | | + | + + +
+<     |   | |   |     >
++-+ + +-+ + + +-+ + +-+
+|   |             |   |
+| + +-+   + +   +-+ + |
+| |   |   | |   |   | |
+| + + + +-+ +-+ + + + |
+|   |             |   |
++*+-+-------------+-+*+
+
+"b3"
++---+-------------+---+
+|   |             |   |
+| + + +-+ +-+ +-+ + + |
+| |   |         |   | |
++ + + | +-+ +-+ | + + +
+<   | |   | |   | |   >
++---+ +-+ | | +-+ +---+
+|         | |         |
+| + +---+ + + +---+ + |
+| |                 | |
+| + +   + +-+ +   + + |
+|   |   |     |   |   |
++*+-+---+-----+---+-+*+
+
+"b4"
++-------+-----+-------+
+|       |     |       |
+| +---+ + + + + +---+ |
+| |       | |       | |
++ + +---+ + + +---+ + +
+<   |             |   >
++-+ | + +-+ +-+ + | +-+
+|   | |         | |   |
+| + + + +-----+ + + + |
+| |                 | |
+| +   + +-+ +-+ +   + |
+|     |         |     |
++*+---+---------+---+*+
+
+"b5"
++-----+---------+-----+
+|     |         |     |
+| +-+ + +-+ +-+ + +-+ |
+|         | |         |
++ +---+ + + + + +---+ +
+<       |     |       >
++-+ +-+ + + + + +-+ +-+
+|     |   | |   |     |
+| +-+ | +-+ +-+ | +-+ |
+|     |         |     |
+| +-+ + + +-+ + + +-+ |
+|       |     |       |
++*+-----+-----+-----+*+
+
+"b6"
++---+-------------+---+
+|   |             |   |
+| + + +-+ +-+ +-+ + + |
+| |                 | |
++ + + +-+ +-+ +-+ + + +
+<   |   |     |   |   >
++-+ |   +-+ +-+   | +-+
+|   |   |     |   |   |
+| + +-+ + +-+ + +-+ + |
+| |                 | |
+| +   + +-+ +-+ +   + |
+|     |         |     |
++*+---+---------+---+*+
+
+"b7"
++-----+---------+-----+
+|     |         |     |
+| +-+ + +-+ +-+ + +-+ |
+| |                 | |
++ + +-+ +-+ +-+ +-+ + +
+<   |     | |     |   >
++-+ + + + | | + + + +-+
+|     | | | | | |     |
+| +-+ + | + + | + +-+ |
+|       |     |       |
+| +-+ +-+ + + +-+ +-+ |
+|         | |         |
++*+-------+-+-------+*+
+
+"b8"
++---------------------+
+|                     |
+| +-+   +-+ +-+   +-+ |
+| |     |     |     | |
++ + +-+ + +-+ + +-+ + +
+<   |             |   >
++-+ + + + +-+ + + + +-+
+|     | |     | |     |
+| +-+ | +-+ +-+ | +-+ |
+|     |         |     |
+| +-+ + + +-+ + + +-+ |
+|       |     |       |
++*+-----+-----+-----+*+
+
+"b9"
++---------------------+
+|                     |
+| +---+ + +-+ + +---+ |
+|       |     |       |
++ +-+ +-+ +-+ +-+ +-+ +
+<     |         |     >
++-+ + + +-+ +-+ + + +-+
+|   |   |     |   |   |
+| +-+ + + + + + + +-+ |
+| |   |   | |   |   | |
+| + +-+ + + + + +-+ + |
+|       |     |       |
++*+-----+-----+-----+*+
+
+"b10"
++-----+---------+-----+
+|     |         |     |
+| +-+ + +-+ +-+ + +-+ |
+|       |     |       |
++ +---+ + +-+ + +---+ +
+<                     >
++-+ + + + + + + + + +-+
+|   | | | | | | | |   |
+| +-+ + | + + | + +-+ |
+|       |     |       |
+| +-+ + +-+ +-+ + +-+ |
+|     |         |     |
++*+---+---------+---+*+
+
+"b11"
++-----+---------+-----+
+|     |         |     |
+| +-+ | + +-+ + | +-+ |
+|     | |     | |     |
++ +-+ + +-+ +-+ + +-+ +
+<   |             |   >
++-+ + + + +-+ + + + +-+
+|     | |     | |     |
+| +---+ + +-+ + +---+ |
+|                     |
+| +-+   + +-+ +   +-+ |
+|       |     |       |
++*+-----+-----+-----+*+
+
+"b12"
++---+-------------+---+
+|   |             |   |
+| + + +-+ +-+ +-+ + + |
+| |   |         |   | |
++ + +-+ + +-+ + +-+ + +
+<       |     |       >
++-+ + + | +-+ | + + +-+
+|   | | |     | | |   |
+| + | + + + + + + | + |
+| | |     | |     | | |
+| + + + +-+ +-+ + + + |
+|     |         |     |
++*+---+---------+---+*+
+
+"w1"
++---------------------+
+|                     |
+| +     +     +     + |
+| |     |     |     | |
++ +-+ +-+ + + +-+ +-+ +
+<   |     | |     |   >
++   + +   | |   + +   +
+|     |   | |   |     |
+| +-+ +-+ + + +-+ +-+ |
+| |     |     |     | |
+| +     +     +     + |
+|                     |
++*+-----------------+*+
+
+"w2"
++---------------------+
+|                     |
+|       +-+ +-+       |
+|       |     |       |
++     +-+     +-+     +
+<     |         |     >
++   +-+   + +   +-+   +
+|   |     | |     |   |
+| +-+   +-+ +-+   +-+ |
+|       |     |       |
+|     +-+     +-+     |
+|                     |
++*+-----------------+*+
+
+"w3"
++---------------------+
+|                     |
+|   +   +-+ +-+   +   |
+|   |     | |     |   |
++ +-+-+ + + + + +-+-+ +
+<   |   |     |   |   >
++ + + +-+-+ +-+-+ + + +
+| |     |     |     | |
+| +-+   +     +   +-+ |
+|   |             |   |
+|   +---+     +---+   |
+|                     |
++*+-----------------+*+
+
+"w4"
++---------------------+
+|                     |
+| +   + +     + +   + |
+| |   | |     | |   | |
++ | + + | + + | + + | +
+< | |   | | | |   | | >
++ + | + + | | + + | + +
+|   | |   | |   | |   |
+|   + | + + + + | +   |
+|     | |     | |     |
+|     + +     + +     |
+|                     |
++*+-----------------+*+
+
+"w5"
++---------------------+
+|                     |
+| +-+     + +     +-+ |
+|   |     | |     |   |
++   | +---+ +---+ |   +
+<   | |         | |   >
++ +-+ + +     + + +-+ +
+|       |     |       |
+|   +---+     +---+   |
+|   |             |   |
+|   +             +   |
+|                     |
++*+-----------------+*+
+
+"w6"
++---------------------+
+|                     |
+| +-+   + +-+ +   +-+ |
+|       |     |       |
++ + +-+ + +-+ + +-+ + +
+< |                 | >
++ |   +-+     +-+   | +
+| |                 | |
+| + +-+ + +-+ + +-+ + |
+|       |     |       |
+| +-+   + +-+ +   +-+ |
+|                     |
++*+-----------------+*+
+
+"w7"
++---------------------+
+|                     |
+| +-+     + +     +-+ |
+|   |     | |     |   |
++   +-+ +-+ +-+ +-+   +
+<     | |     | |     >
++     | |     | |     +
+|     | |     | |     |
+|   +-+ +-+ +-+ +-+   |
+|   |     | |     |   |
+| +-+     + +     +-+ |
+|                     |
++*+-----------------+*+
+
+"w8"
++---------------------+
+|                     |
+| +-+   +-+ +-+   +-+ |
+|   |             |   |
++   +-+   +-+   +-+   +
+<     |         |     >
++     +-+     +-+     +
+|       |     |       |
+|   +   +-+ +-+   +   |
+|   |     | |     |   |
+|   +     + +     +   |
+|                     |
++*+-----------------+*+
diff --git a/data/sprites.txt b/data/sprites.txt
--- a/data/sprites.txt
+++ b/data/sprites.txt
@@ -1,1065 +1,1065 @@
-r 255   0   0 255
-b  65 161 255 255
-y 237 202   0 255
-
-[blue-worrior-walk]
-
-"            bbb     "
-"           r bbb    "
-"             bbb  b "
-"          bbbbb     "
-"            bbb bb  "
-"            bbbbbbb "
-"           bbrrbrbb "
-"  b b     bbbrrbrb  "
-" rbrbrrrrrrrrrrbrb  "
-"  b b   rrrrrrbbbb  "
-"          bbbbb bb  "
-"            bbbb    "
-"           bbbbb    "
-"          bbbbbb    "
-"         bbb  bb    "
-"        bbb   bbb   "
-"        bb     bb   "
-"      bbbb   bbbb   "
-
-"            bbb     "
-"           r bbb    "
-"             bbb  b "
-"          bbbbb     "
-"            bbb bb  "
-"            bbbbbbb "
-"           bbrrbrbb "
-"  b b     bbbrrbrb  "
-" rbrbrrrrrrrrrrbrb  "
-"  b b   rrrrrrbbbb  "
-"          bbbbb bb  "
-"           bbbb     "
-"            bb      "
-"            bb      "
-"            bb      "
-"            bb      "
-"            bb      "
-"          bbbb      "
-
-"            bbb     "
-"           r bbb    "
-"             bbb  b "
-"          bbbbb     "
-"            bbb bb  "
-"            bbbbbbb "
-"           bbrrbrbb "
-"  b b     bbbrrbrb  "
-" rbrbrrrrrrrrrrbrb  "
-"  b b   rrrrrrbbbb  "
-"          bbbbb bb  "
-"           bbbb     "
-"            bbbb    "
-"            bbbbb   "
-"           bb bbb   "
-"           bb  bbb  "
-"           bb    b  "
-"         bbbb  bbb  "
-
-[blue-worrior-shoot]
-
-"             bbb    "
-"            r bbb r "
-"              bbb   "
-"           bbbbb    "
-"   y         bbb bb "
-" rr          brrbbb "
-"  yy  b b   bbbrrbb "
-" yyyyrbrbrrrrrrrrbb "
-" ryy  b b  rrrrrbbb "
-"            bbbbbbb "
-"            bbbbbbb "
-"           bbbbbb   "
-"          bbbbbbb   "
-"     b   bbb bbb    "
-"      b bbb  bbb    "
-"      bbbb    bbb   "
-"       bb      bb   "
-"             bbbb   "
-
-" r r          bbb   "
-"  ryy        r bbbr "
-" ryyyy         bbb  "
-"  yyyy      bbbbb   "
-" r    rb      bbbb  "
-"      brb      bbbb "
-"    y  brr    bbrbb "
-"         rrr bbrrrb "
-"  r       rrrrrrrbb "
-"            rrrrbbb "
-"            bbbbbbb "
-"    b    bbbbbbbbb  "
-"     b  bbbbbbbbbb  "
-"     bbbbb     bbb  "
-"      bb       bbb  "
-"              bbb   "
-"              bbb   "
-"           bbbbb    "
-
-"  r   y       bbb   "
-"             r bbbr "
-" y r           bbb  "
-"   yy  r    bbbbb   "
-"  yyyy        bbb b "
-" r yyy        bbbbb "
-"  r   rbr    bbbrbb "
-"      brrrrr bbrrrb "
-"        rrrrrrrrrbb "
-"           rrrrrbbb "
-"            bbbbbbb "
-"          bbbbbbb   "
-"     b   bbbbbbbb   "
-"      b bbb   bbb   "
-"      bbbb    bbb   "
-"       bb     bb    "
-"              bb    "
-"           bbbbb    "
-
-"             bbb    "
-"   y        r bbb r "
-"     r        bbb   "
-"           bbbbb    "
-"   y         bbb bb "
-" rr          brrbbb "
-"  yy  b b   bbbrrbb "
-" yyyyrbrbrrrrrrrrbb "
-" ryy  b b  rrrrrbbb "
-"            bbbbbbb "
-"            bbbbbbb "
-"          bbbbbbb   "
-"          bbbbbbb   "
-"         bbb  bbb   "
-"      bb bb   bbb   "
-"       bbb     bb   "
-"        bb     bb   "
-"             bbbb   "
-
-[yellow-worrior-walk]
-
-"            yyy     "
-"           r yyy    "
-"             yyy  y "
-"          yyyyy     "
-"            yyy yy  "
-"            yyyyyyy "
-"           yyrryryy "
-"  y y     yyyrryry  "
-" ryryrrrrrrrrrryry  "
-"  y y   rrrrrryyyy  "
-"          yyyyy yy  "
-"            yyyy    "
-"           yyyyy    "
-"          yyyyyy    "
-"         yyy  yy    "
-"        yyy   yyy   "
-"        yy     yy   "
-"      yyyy   yyyy   "
-
-"            yyy     "
-"           r yyy    "
-"             yyy  y "
-"          yyyyy     "
-"            yyy yy  "
-"            yyyyyyy "
-"           yyrryryy "
-"  y y     yyyrryry  "
-" ryryrrrrrrrrrryry  "
-"  y y   rrrrrryyyy  "
-"          yyyyy yy  "
-"           yyyy     "
-"            yy      "
-"            yy      "
-"            yy      "
-"            yy      "
-"            yy      "
-"          yyyy      "
-
-"            yyy     "
-"           r yyy    "
-"             yyy  y "
-"          yyyyy     "
-"            yyy yy  "
-"            yyyyyyy "
-"           yyrryryy "
-"  y y     yyyrryry  "
-" ryryrrrrrrrrrryry  "
-"  y y   rrrrrryyyy  "
-"          yyyyy yy  "
-"           yyyy     "
-"            yyyy    "
-"            yyyyy   "
-"           yy yyy   "
-"           yy  yyy  "
-"           yy    y  "
-"         yyyy  yyy  "
-
-[yellow-worrior-shoot]
-
-"             yyy    "
-"            r yyy r "
-"              yyy   "
-"           yyyyy    "
-"   y         yyy yy "
-" rr          yrryyy "
-"  yy  y y   yyyrryy "
-" yyyyryryrrrrrrrryy "
-" ryy  y y  rrrrryyy "
-"            yyyyyyy "
-"            yyyyyyy "
-"           yyyyyy   "
-"          yyyyyyy   "
-"     y   yyy yyy    "
-"      y yyy  yyy    "
-"      yyyy    yyy   "
-"       yy      yy   "
-"             yyyy   "
-
-" r r   b      yyy   "
-"  ryy        r yyyr "
-" ryyyy         yyy  "
-"  yyyy      yyyyy   "
-" r    ry      yyyy  "
-"      yry      yyyy "
-"    b  yrr    yyryy "
-"         rrr yyrrry "
-"  r       rrrrrrryy "
-"            rrrryyy "
-"            yyyyyyy "
-"    y    yyyyyyyyy  "
-"     y  yyyyyyyyyy  "
-"     yyyyy     yyy  "
-"      yy       yyy  "
-"              yyy   "
-"              yyy   "
-"           yyyyy    "
-
-"  b   y       yyy   "
-"             r yyyr "
-" y r           yyy  "
-"   yy  r    yyyyy   "
-"  yyyy        yyy y "
-" r yyy        yyyyy "
-"  b   ryr    yyyryy "
-"      yrrrrr yyrrry "
-"        rrrrrrrrryy "
-"           rrrrryyy "
-"            yyyyyyy "
-"          yyyyyyy   "
-"     y   yyyyyyyy   "
-"      y yyy   yyy   "
-"      yyyy    yyy   "
-"       yy     yy    "
-"              yy    "
-"           yyyyy    "
-
-"             yyy    "
-"   y        r yyy r "
-"     r        yyy   "
-"           yyyyy    "
-"   y         yyy yy "
-" rr          yrryyy "
-"  yy  y y   yyyrryy "
-" yyyyryryrrrrrrrryy "
-" ryy  y y  rrrrryyy "
-"            yyyyyyy "
-"  b         yyyyyyy "
-"          yyyyyyy   "
-"          yyyyyyy   "
-"         yyy  yyy   "
-"      yy yy   yyy   "
-"       yyy     yy   "
-"        yy     yy   "
-"             yyyy   "
-
-[burwor-walk]
-
-"                b   "
-"               bbb  "
-"               bbb  "
-"           b   bbbb "
-"     bbbbbb    bbbb "
-"    bbrrbbb b  bbb  "
-" bbbbrrrbbbb   bbb  "
-" bbbbbbbbbbbb  bb   "
-" bbbbbbbbbb    b    "
-"  bbbb  bbb   b     "
-"        bbb  b      "
-"   bbb   bbbb    bb "
-"   bbbb  bbbbb bbbb "
-"    bbbbbbbbbbbbbb  "
-"    bbb bbbbbb bbb  "
-"     bb  bbbbb bb   "
-"      bb       b    "
-"   bbbbbb     bbbbb "
-
-"                 bb "
-"     bbbbbbb    bb  "
-"    bbrrbbb    bbbb "
-" bbbbrrrbbbbb  bbbb "
-" bbbbbbbbbbb    bbb "
-"  b b bbbbbbb  bbb  "
-" bbbbbbbbbb    bb   "
-"  bbbb  bbbb  bb    "
-"        bbb   b     "
-"        bbbb b      "
-"   bbbbbbbbbbbb     "
-"  bbbbbbbbbbbbbb    "
-"   bbb  bbbbbbbbb   "
-"    bb       bbbb   "
-"     bb       bb    "
-"  bbbbbb       b    "
-"              bbb   "
-"                 bb "
-
-"     bbbbbbb   bbb  "
-"    bbrrbbb   bbbbb "
-" bbbbrrrbbbbb bbb   "
-" bbbbbbbbbbb  bb    "
-"  b b bbbbbbb bb    "
-"      bbbbb    bb   "
-"  bbbb  bbbb   bb   "
-"        bbb   b     "
-"       bbbbb b      "
-"     bbbbbbbbbb     "
-"   bbbbbbbbbbbbbb   "
-"  bbbb        bbbb  "
-"   bb          bb   "
-"    bb        bb    "
-"   bbbb      bbbb   "
-"  b              b  "
-" b                b "
-"                    "
-
-[burwor-shoot]
-
-"                b   "
-"               bbb  "
-"            b  bbb  "
-"      bbbbbb   bbbb "
-"     bbrrbbb b bbbb "
-"  bbbbrrrbbbb  bbbb "
-"  bbbbbbbbbbb  bbb  "
-"  rbrbrbbbbbbb bbb  "
-" rbbbbbbbbbb   bb   "
-"   bbbb  bbb   b    "
-" r       bbbb b     "
-"   bbb   bbbbb   bb "
-"   bbbb  bbbbb bbbb "
-"    bbbbbbbbbbbbbb  "
-"    bbb bbbbbb bbb  "
-"     bb  bbbbb bb   "
-"      bb       b    "
-"   bbbbbb     bbbbb "
-
-"               b    "
-"               bb   "
-"            b  bbb  "
-"      bbbbbb   bbbb "
-"     bbrrbbb b bbbb "
-"  bbbbrrrbbbb  bbbb "
-"  bbbbbbbbbbb  bbb  "
-"  rbrbbbbbbbbb bbb  "
-" rrrrrrbbbbb   bb   "
-"   bbbb  bbb   b    "
-" r       bbbb b     "
-"   bbb   bbbbb   bb "
-"   bbbb  bbbbb bbbb "
-"    bbbbbbbbbbbbbb  "
-"  r bbb bbbbbb bbb  "
-"     bb  bbbbb bb   "
-"      bb       b    "
-" r bbbbbb     bbbbb "
-
-"       bbbbbb    b  "
-"      bbrrbb    bbb "
-"   bbbbrrrbbbb bbbb "
-"   bbbbbbbbbb  bbbb "
-" r  brbrbbbbbb bbbb "
-"  rrrrrrrbbb   bbbb "
-" rryrrrrbbbbb  bbb  "
-"  y bbbb bbb   bb   "
-"         bbbb bb    "
-" r     bbbbbbbb     "
-"   bbbbbbbbbbbb     "
-"  bbbbbbbbbbbbbb    "
-"   bbb  bbbbbbbbb   "
-" y  bb       bbbb   "
-"     bb       bb    "
-"  bbbbbb       b    "
-"         r    bbb   "
-"      r          bb "
-
-"        bbbbbb    b "
-"       bbrrbb    bb "
-"    bbbbrrrbbbb bbb "
-"    bbbbbbbbbb  bbb "
-" y   brbrbbbbbb bbb "
-"  rrrrrrrrbbb   bbb "
-" rrryrrrrbbbbb  bb  "
-"   y bbbb bbb  bb   "
-"          bbbbbb    "
-"      bbbbbbbbb     "
-"    bbbbbbbbbbbbb   "
-"   bbbbb      bbbb  "
-"    bb         bb   "
-"     bb       bb    "
-"    bbbb     bbbb   "
-"   b       r     b  "
-"  b  y            b "
-"         r          "
-
-[garwor-walk]
-
-"               rr   "
-"       yyyyy    rrr "
-"      yyyyyyy    rr "
-"    yyyy  yyyy    y "
-"  yyyyyyb yyyyy   y "
-"  yyyyyyyyyyyyyy  y "
-"    yryryyyyyyyy  y "
-"  rrrrrryyyyyyyyy y "
-" r yryryy yyyyyyy y "
-"    yyyy yyyyyyyy y "
-"         yyyyyyyyyy "
-"        yyyyyyyyyyy "
-"      yyyyyyyyyyyy  "
-"     y   yyyyyyyy   "
-"          yyyyy     "
-"          yyy  y    "
-"          yy   y    "
-"        yyy   yy    "
-
-"      yyyyy      rr "
-"     yyyyyy    rrr  "
-"   yyyy  yyy   rr   "
-" yyyyyyb yyyy  y    "
-" yyyyyyyyyyyy  y    "
-"   yryryryyyyy yyyy "
-"   rrrrrryyyyy    y "
-"  yryryryyyyyyy   y "
-"   yyyyyyyyyyyyy yy "
-"       yyyyyyyyy y  "
-"       yyyyyyyyyyy  "
-"       yyyyyyyyyyy  "
-"      y yyyyyyyyy   "
-"     y  yyyyyyyy    "
-"         yyyyy      "
-"          yy  yyy   "
-"           y    y   "
-"         yyy        "
-
-"       yyyyy    rrr "
-"      yyyyyy   rrr  "
-"    yyyy  yyy  rrr  "
-"  yyyyyyb yyyy  y   "
-"  yyyyyyyyyyyy  yyy "
-"    yryryryyyyy   y "
-"  rrrrrrrryyyyy   y "
-" r yryryryyyyyyy  y "
-"    yyyyyyyyyyyy  y "
-"        yyyyyyyyy y "
-"        yyyyyyyyyyy "
-"       yyyyyyyyyyyy "
-"         yyyyyyyyy  "
-"          yyyyyyy   "
-"         yyyyyy     "
-"        yy  yy      "
-"         yy  y      "
-"          y yy      "
-
-[garwor-shoot]
-
-"               rr   "
-"        yyyyy   rrr "
-"       yyyyyyy   rr "
-"     yyyy  yyyy   y "
-"   yyyyyyb yyyyy  y "
-" b yyyyyyyyyyyyyy y "
-"    ryryryyyyyyyy y "
-"  rrrrrrryyyyyyyyy  "
-" y  rryryy yyyyyyy  "
-"    yyyyy yyyyyyyyy "
-"  r       yyyyyyyyy "
-"         yyyyyyyyyy "
-"       yyyyyyyyyyy  "
-"      y   yyyyyyyy  "
-"           yyyyy    "
-"           yyy  y   "
-"           yy   y   "
-"         yyy   yy   "
-
-"        yyyyy   r   "
-"       yyyyyy  rrr  "
-"     yyyy  yyy rrr  "
-"   yyyyyyb yyyy rr  "
-" r yyyyyyyyyyyy y   "
-"     yryryryyyyy y  "
-" by  rrrrrryyyyy  y "
-" yyrrrrrrryyyyyyy y "
-" ryb rrryyyyyyyyy y "
-" yy  yyyyyyyyyyyyyy "
-"  b      yyyyyyyyyy "
-"         yyyyyyyyyy "
-"        y yyyyyyyyy "
-"       y  yyyyyyyy  "
-"           yyyyy    "
-"            yy  yyy "
-"             y    y "
-"           yyy      "
-
-"        yyyyy   rrr "
-"       yyyyyy  rrr  "
-" r   yyyy  yyy rrr  "
-"   yyyyyyb yyyyrr   "
-" y yyyyyyyyyyyy y   "
-" b   yryryryyyyy y  "
-" bb rrrrrrryyyyy  y "
-" yrrrrrrrryyyyyyy y "
-"  yb rrryyyyyyyyy y "
-" yr  yyyyyyyyyyyyyy "
-" rr      yyyyyyyyyy "
-"  ryy    yyyyyyyyyy "
-"   yb   y yyyyyyyyy "
-"       y  yyyyyyyy  "
-"           yyyyy    "
-"            yy  yyy "
-"             y    y "
-"           yyy      "
-
-"        yyyyy  rr   "
-" r     yyyyyy   rrr "
-"     yyyy  yyy   rr "
-"   yyyyyyb yyyy   y "
-" b yyyyyyyyyyyy   y "
-"     yryryryyyyy  y "
-"  rrrrrrrrryyyyy  y "
-"   rrrrrrryyyyyyy y "
-" y   rrryyyyyyyyy y "
-"   b yyyyyyyyyyyy y "
-" r       yyyyyyyyyy "
-"       yyyyyyyyyyyy "
-"    b    yyyyyyyyy  "
-"          yyyyyyy   "
-"         yyyyyy     "
-"        yy  yy      "
-"         yy  y      "
-"          y yy      "
-
-[thorwor-walk]
-
-"                rr  "
-"      yy       rr   "
-"     y  r     rrr   "
-"    y  rrr    r     "
-"      rrrrr   rr    "
-"     rr rrrr   r    "
-"    rr  rrrr   rrr  "
-"    rr brrrrr    r  "
-"  rrrrrrrrrrrr   rr "
-" rrrrrrrrrrrrrrrrrr "
-"    rrrrrrrrrrrrrr  "
-" rr    rrrrrrrrrrr  "
-" rrrrrrrrrrrrrrrr   "
-"    rrrr  r  r  r   "
-"          r  r  r   "
-"         rr rr rr   "
-"         r  r  r    "
-"        bb bb bb    "
-
-"                rr  "
-"      yy        r   "
-"     y  r       r   "
-"    y  rrr      rr  "
-"      rrrrr      r  "
-"     rr rrrr     r  "
-"    rr  rrrr     r  "
-"   rrr brrrrr    rr "
-" rrrrrrrrrrrrr   rr "
-" rr  rrrrrrrrrrrrrr "
-"   b  rrrrrrrrrrrr  "
-"       rrrrrrrrrrr  "
-" r b rrrrrrrrrrrr   "
-" rrrrrrrr r  r  r   "
-"   rrrr   r  r  r   "
-"          r  r  r   "
-"          r  r  r   "
-"         bb bb bb   "
-
-"    y y    rrrr     "
-"       y      rrr   "
-"        r       r   "
-"       rrr      r   "
-"    rrrrrrr     r   "
-"     rr rrrr    rr  "
-"    rr  rrrr     r  "
-"  rrrr brrrrr    rr "
-" rr  rrrrrrrrr   rr "
-" r b  rrrrrrrrrrrrr "
-"   b   rrrrrrrrrrr  "
-"       rrrrrrrrrrr  "
-"      rrrrrrrrrrr   "
-" r b  rrr r  r  r   "
-" rr  rrr  r  r  r   "
-"  rrrrr   rr rr rr  "
-"           r  r  r  "
-"          bb bb bb  "
-
-[thorwor-shoot]
-
-"          yyy     r "
-"         rr  yy   r "
-"        rrrr   yyr  "
-"       rr rrr  rr   "
-"   rrrrr  rrrr  rr  "
-"  r   r  brrrr    r "
-" r b   rrrrrrr    r "
-"       rrrrrrr    r "
-"   yyyyyrrrrrrr  rr "
-"     yyyrrrrrrrrrrr "
-" r b   rrrrrrrrrrr  "
-"  r   rrrrrrrrrrrr  "
-"  rr rrr rrrrrrrr   "
-"    rrr   r  r  r   "
-"          r  r  r   "
-"         rr rr rr   "
-"         r  r  r    "
-"         bb bb bb   "
-
-"            yy   r  "
-"        rrrr  y  r  "
-"    rrrrrr rr  yr   "
-"  rr rrr   rr   y   "
-"    b rr brrr  ry   "
-" y  b  rrrrrrr r y  "
-" yy     rrrrrr  r   "
-"  yyyyyyrrrrrrr  r  "
-"    yyyyrrrrrrr   r "
-" r b  yrrrrrrrrr rr "
-"  r   rrrrrrrrrrrrr "
-"  rr rrrrrrrrrrrrrr "
-"    rrr  rrrrrrrrr  "
-"          r  rr rr  "
-"          rr  r  r  "
-"           rr rr rr "
-"            r  r  r "
-"           bb bb bb "
-
-"            yy   r  "
-"        rrrr  y rrr "
-"    rrrrrr rr y r r "
-"  rr rrr   rr y r   "
-"    b rr brrr y r   "
-" yy    rrrrrrr y r  "
-"   yy   rrrrrr  yr  "
-"    yyyyrrrrrrr  r  "
-"     yyyrrrrrrr  r  "
-" r b   rrrrrrrrr rr "
-"  r   rrrrrrrrrrrrr "
-"  rr rrrrrrrrrrrrrr "
-"    rrr  rrrrrrrrr  "
-"           r  r  r  "
-"           r  r  r  "
-"          rr rr rr  "
-"          r  r  r   "
-"          bb bb bb  "
-
-"            y   rrr "
-"        rrrr y rr r "
-"    rrrrrr rr yr  r "
-"  rr rrr   rr  y rr "
-" y  b rr brrr  yr   "
-" yy    rrrrrrr y r  "
-"  yyyy  rrrrrr    r "
-"    yyy rrrrrrr   r "
-"     yyyrrrrrrr   r "
-" r b  yrrrrrrrrr rr "
-"  r   rrrrrrrrrrrrr "
-"  rr rrrrrrrrrrrrrr "
-"    rrr  rrrrrrrrr  "
-"          r  rr rr  "
-"          rr  r  r  "
-"           rr rr rr "
-"            r  r  r "
-"           bb bb bb "
-
-[worluk-walk]
-
-"      bb     bb  yy "
-" yy     b   b   yyy "
-" yyy   yryyyry  yyy "
-" yyyy yrrryrrryyyyy "
-" yyyyyrrrryrrrryyyy "
-" bbyyy yryyyryyyyyb "
-"  bbyyy  yyy  yyybb "
-"  bybbyy byb yybb b "
-"  b  ybybbbbbyby  b "
-"   b   bbbbbbby   b "
-"    b   bbbbb    b  "
-"        bbbbb       "
-"        bbbbb       "
-"      bbbbbbbbb     "
-"     b  bbbbb  b    "
-"     b   bbb   b    "
-"     b    b    b    "
-"   bbb         bbb  "
-
-"       b    b       "
-"       b   b        "
-"      yryyyry       "
-"  y  yrrryrrry      "
-" bby rrrryrrrr  yyy "
-" ybyy yryyyry  yyyy "
-" ybbyy  yyy  yyyybb "
-" ybybyy byb yybbbby "
-" ybyybybbbbbybyybby "
-" yybyybbbbbbbyyybyy "
-"  yybyybbbbbyyybyy  "
-"   yyy bbbbb yyyy   "
-"       bbbbb        "
-"    bbbbbbbbb       "
-"    b  bbbbb b      "
-"     b  bbb   b     "
-"      b  b     b    "
-"    bbb        bbb  "
-
-"                    "
-"         b   b      "
-"        b   b       "
-"       yryyyry      "
-"      yrrryrrry     "
-"      rrrryrrrr     "
-"       yryyyry      "
-"    yyy  yyy  yyy   "
-" bbbbbby byb ybbbbb "
-"  byyyybbbbbbbyybb  "
-"  ybyyyybbbbbyybyyy "
-"  yybyy bbbbb byyyy "
-" yyyyy  bbbbb  yyyy "
-" yyyybbbbbbbbbbbyyy "
-" yyy b  bbbbb  byyy "
-" yy   b  bbb  b  yy "
-"       b  b  b      "
-"     bbbb   bbbb    "
-
-[wizard-walk]
-
-"         bbbb       "
-"       bbbbb        "
-"      b    b        "
-"      by y bbb      "
-"      bb  bbbbb     "
-"     bbbb bbbbbbb   "
-"    bb  bbbbb   bb  "
-"    b    bbbb    bb "
-"   bb    bbbbb    r "
-" rr      bbbbb    r "
-"        bbbbbb      "
-"       bbbbbbb      "
-"     bbbbbbbbbb     "
-"     bbbbbbbbbb     "
-"      bbbbbbbbbb    "
-"      bbbbbbbbbbb   "
-"       bbbbbbbbbbb  "
-"      bbbbbbbbbbbb  "
-
-"      bbbb          "
-"     b  bbb         "
-"     by ybb         "
-"     bb  bbbb       "
-"      bb bbbbb      "
-"     bbbbbbb bb     "
-"      b bbbb  bb    "
-"     b   bbbb  bb   "
-"    bb   bbbbb  r   "
-"  rr    bbbbbb  r   "
-"       bbbbbbb      "
-"      bbbbbbb       "
-"     bbbbbbbbb      "
-"      bbbbbbbbb     "
-"       bbbbbbbbb    "
-"        bbbbbbbbb   "
-"        bbbbbbbb    "
-"      bbbbb         "
-
-"         bbb        "
-"      bbbbb         "
-"     b bbbb         "
-"     by bbb         "
-"     bb  bbbb       "
-"      bb bbbbb      "
-"      bbbbbb bb     "
-"        bbbbb bb    "
-"       b bbbbbbb    "
-"      bb bbbbbr     "
-"    rr  bbbbbrr     "
-"       bbbbbbbb     "
-"      bbbbbbbb      "
-"      bbbbbbbb      "
-"       bbbbbb       "
-"       bbbbbb       "
-"      bbbbbbbb      "
-"      bbbbbbbb      "
-
-"       bbbb         "
-"      b  bbb        "
-"      by ybb        "
-"      bb  bbb       "
-"       bb bbbbb     "
-"       bbbbbbbbb    "
-"       bbbbbb  bb   "
-"      bb bbbb   b   "
-"     bb   bbbb  bb  "
-"   rr   bbbbbb   r  "
-"      bbbbbbbb   r  "
-"     bbbbbbbbb      "
-"     bbbbbbbb       "
-"      bbbbbbb       "
-"      bbbbbbb       "
-"       bbbbbbb      "
-"     bbbbbbbbb      "
-"         bbbbb      "
-
-[wizard-shoot]
-
-"         bbbb       "
-"        b   bb      "
-"   r    by ybb      "
-" rrrr   bb  b       "
-"    rb   b  b  rrrr "
-"    bb bbbb bbb rrb "
-"    bbbbbbbbbbbbrbb "
-"     bbbbbbbb bbbb  "
-"         bbbb  bb   "
-"         bbbb       "
-"        bbbbb       "
-"       bbbbbbb      "
-"      bbbbbbbb      "
-"     bbbbbbbbb      "
-"     bbbbbbbbbb     "
-"     bbbbbbbbbb     "
-"    bbbbbbbbbbb     "
-"   bbbbbbbbbbbbb    "
-
-"           bbb      "
-"          bb bbb    "
-"          by ybbb   "
-"          b   bb    "
-" rrrr  bbbbb  b     "
-"    rr bbbbb bbbb   "
-"     rr   bbrrrrrb  "
-"     rr   bbbbb rrr "
-"          bbbb   rr "
-"          bbb       "
-"         bbbbb      "
-"        bbbbbb      "
-"       bbbbbbb      "
-"       bbbbbb       "
-"       bbbbbb       "
-"      bbbbbbbb      "
-"      bbbbbbbbb     "
-"    bbbbbbbbbbbb    "
-
-"             bbbb   "
-"            bbbbbb  "
-"    rrrbb    ybbbbb "
-" yy   rbbbb    bbb  "
-"    rr   bbbbbbbb   "
-" yyy rrbbbbbbbbbbb  "
-"      rbb    bbbbb  "
-"       b      bbbb  "
-"              bbbb  "
-"             bbbb   "
-"           bbbbbb   "
-"          bbbbbbb   "
-"         bbbbbbb    "
-"         bbbbbbb    "
-"         bbbbbbb    "
-"        bbbbbbbbb   "
-"        bbbbbbbbbb  "
-"      bbbbbbbbbbbbb "
-
-[worrior-flash]
-
-"         rrbbbrr    "
-"         ryrbbbr    "
-"        rrrrbbbr    "
-"        rbbbbbrrrr  "
-"        rrrbbbrbbr  "
-"          rbbbbbbb  "
-" r r     rbbyybybb  "
-"rbrbrrrrrbbbyybybr  "
-"ybybyyyyyyyyyybbbr  "
-"rbrbrrryyyyyybbbbr  "
-" r r  rrrbbbbbrbbr  "
-"         rbbbbrrrr  "
-"         rbbbbbr    "
-"        rbbbbbbr    "
-"       rbbbrrbbr    "
-"      rbbbr rbbbr   "
-"    rrrbbr  rrbbr   "
-"    rbbbbr rbbbbr   "
-
-"         rryyyrr    "
-"         rbryyyr    "
-"        rrrryyyr    "
-"        ryyyyyrrrr  "
-"        rrryyyryyr  "
-"          ryyyyyyy  "
-" r r     ryybbybyy  "
-"ryryrrrrryyybbybyr  "
-"bybybbbbbbbbbbyyyr  "
-"ryryrrrbbbbbbyyyyr  "
-" r r  rrryyyyyryyr  "
-"         ryyyyrrrr  "
-"         ryyyyyr    "
-"        ryyyyyyr    "
-"       ryyyrryyr    "
-"      ryyyr ryyyr   "
-"    rrryyr  rryyr   "
-"    ryyyyr ryyyyr   "
-
-[blue-worrior-death]
-
-"                    "
-"              b     "
-"b b          bb     "
-"bybyyyyyy    bb y   "
-"b b   yyy    bbbbb  "
-"           b   bb   "
-"        y   y  r    "
-"       rbb y   b    "
-"             r y    "
-"         b b  b b   "
-"        b ry   y    "
-"     bb  y   yb r   "
-"    bbb    b        "
-"   bbb         bbb  "
-"   bb         bbbb  "
-" bbbb         bb b  "
-"                 b  "
-"                    "
-
-[yellow-worrior-death]
-
-"              y     "
-"y y          yy     "
-"ybybbbbbb    yy b   "
-"y y   bbb    yyyyy  "
-"         y    yyyy  "
-"           y   yy   "
-"        b   b  r    "
-"       ryy b   y    "
-"             r b    "
-"         y y  y y   "
-"        y rb   b    "
-"     yy  b   by r   "
-"    yyy    y        "
-"   yyy         yyy  "
-"   yy         yyyy  "
-" yyyy         yy y  "
-"                 y  "
-"                    "
-
-[common-death]
-
-"      y  b          "
-" b r   y   y b      "
-"    y b r    r      "
-"    r  b  b         "
-"  y           r     "
-"    b     by        "
-"r     ry   r b r    "
-"   r    b y         "
-"   y   b   b y      "
-"b     b  b     b    "
-"         y  y       "
-" r   y r      r     "
-"   b  b  y  r b     "
-" y r   y   r   b    "
-"   b y   r   r b    "
-"     r  y   b b     "
-"      b   y         "
-"                    "
-
-"         r   y      "
-"     y      b       "
-" y  r    b    y     "
-"      b     y   b   "
-"    b        y      "
-" r       b   r      "
-"    y      y     b  "
-"b     b  r     r    "
-"   r           y    "
-"        y           "
-" r   y   r     b    "
-"   b   y      r  b  "
-"   b    y  b    y   "
-"b     r       r     "
-"   y b   b     r    "
-"       r      y     "
-"    b      b        "
-"       r            "
-
-[explosion]
-
-"                    "
-"                    "
-"                    "
-"    r     b         "
-"r   rr r            "
-" rrrrrrr  r         "
-"  rrrrrrrrr         "
-"  rrrbrrbrrr        "
-"rrrrbbbbbrr         "
-"rrrbbbbbbrr         "
-" rrrrrbbbrr         "
-"  rr rrrrr          "
-"b r   rrr  b        "
-"      rrr           "
-"       r            "
-"                    "
-"                    "
-"                    "
-
-"   b                "
-"    b               "
-"    bbb             "
-"     bb   b         "
-"     bbbbbb     r   "
-"     brbbbb  bb     "
-"    bbrrrbbbbbbb    "
-"    bbrrrrrrrrbb    "
-"r  bbrrrrrrrrrb     "
-" bbbbrrrrrrrrbb     "
-" bbbrrrrrrrrrbb     "
-"  bbrrrrrrrrrrbb    "
-"  bbrrbbrrrbrrb     "
-"    bbbbbbbbbbb     "
-"  bb bb  bb b bbb   "
-"  b         b   b   "
-"bb          b       "
-"                    "
-
-"         y          "
-"y       y       y   "
-" y     y       y    "
-"  y    y      y     "
-"   yy yyy yy  y     "
-"    yyrrrryyy y     "
-"   yyrrrrrryyy      "
-"   yyrrrrrrryy   y  "
-"  yyrrrrrrrryy      "
-"  yyrrrrrrrryy      "
-"  yyrrrrrrrryy      "
-"  yyyrrrrrrrryy     "
-" y  yryyyrrrry      "
-"y   yy  yyrryyy     "
-"         yyyy yyy   "
-"         y      y   "
-"        y           "
-"       y            "
+r 255   0   0 255
+b  65 161 255 255
+y 237 202   0 255
+
+[blue-worrior-walk]
+
+"            bbb     "
+"           r bbb    "
+"             bbb  b "
+"          bbbbb     "
+"            bbb bb  "
+"            bbbbbbb "
+"           bbrrbrbb "
+"  b b     bbbrrbrb  "
+" rbrbrrrrrrrrrrbrb  "
+"  b b   rrrrrrbbbb  "
+"          bbbbb bb  "
+"            bbbb    "
+"           bbbbb    "
+"          bbbbbb    "
+"         bbb  bb    "
+"        bbb   bbb   "
+"        bb     bb   "
+"      bbbb   bbbb   "
+
+"            bbb     "
+"           r bbb    "
+"             bbb  b "
+"          bbbbb     "
+"            bbb bb  "
+"            bbbbbbb "
+"           bbrrbrbb "
+"  b b     bbbrrbrb  "
+" rbrbrrrrrrrrrrbrb  "
+"  b b   rrrrrrbbbb  "
+"          bbbbb bb  "
+"           bbbb     "
+"            bb      "
+"            bb      "
+"            bb      "
+"            bb      "
+"            bb      "
+"          bbbb      "
+
+"            bbb     "
+"           r bbb    "
+"             bbb  b "
+"          bbbbb     "
+"            bbb bb  "
+"            bbbbbbb "
+"           bbrrbrbb "
+"  b b     bbbrrbrb  "
+" rbrbrrrrrrrrrrbrb  "
+"  b b   rrrrrrbbbb  "
+"          bbbbb bb  "
+"           bbbb     "
+"            bbbb    "
+"            bbbbb   "
+"           bb bbb   "
+"           bb  bbb  "
+"           bb    b  "
+"         bbbb  bbb  "
+
+[blue-worrior-shoot]
+
+"             bbb    "
+"            r bbb r "
+"              bbb   "
+"           bbbbb    "
+"   y         bbb bb "
+" rr          brrbbb "
+"  yy  b b   bbbrrbb "
+" yyyyrbrbrrrrrrrrbb "
+" ryy  b b  rrrrrbbb "
+"            bbbbbbb "
+"            bbbbbbb "
+"           bbbbbb   "
+"          bbbbbbb   "
+"     b   bbb bbb    "
+"      b bbb  bbb    "
+"      bbbb    bbb   "
+"       bb      bb   "
+"             bbbb   "
+
+" r r          bbb   "
+"  ryy        r bbbr "
+" ryyyy         bbb  "
+"  yyyy      bbbbb   "
+" r    rb      bbbb  "
+"      brb      bbbb "
+"    y  brr    bbrbb "
+"         rrr bbrrrb "
+"  r       rrrrrrrbb "
+"            rrrrbbb "
+"            bbbbbbb "
+"    b    bbbbbbbbb  "
+"     b  bbbbbbbbbb  "
+"     bbbbb     bbb  "
+"      bb       bbb  "
+"              bbb   "
+"              bbb   "
+"           bbbbb    "
+
+"  r   y       bbb   "
+"             r bbbr "
+" y r           bbb  "
+"   yy  r    bbbbb   "
+"  yyyy        bbb b "
+" r yyy        bbbbb "
+"  r   rbr    bbbrbb "
+"      brrrrr bbrrrb "
+"        rrrrrrrrrbb "
+"           rrrrrbbb "
+"            bbbbbbb "
+"          bbbbbbb   "
+"     b   bbbbbbbb   "
+"      b bbb   bbb   "
+"      bbbb    bbb   "
+"       bb     bb    "
+"              bb    "
+"           bbbbb    "
+
+"             bbb    "
+"   y        r bbb r "
+"     r        bbb   "
+"           bbbbb    "
+"   y         bbb bb "
+" rr          brrbbb "
+"  yy  b b   bbbrrbb "
+" yyyyrbrbrrrrrrrrbb "
+" ryy  b b  rrrrrbbb "
+"            bbbbbbb "
+"            bbbbbbb "
+"          bbbbbbb   "
+"          bbbbbbb   "
+"         bbb  bbb   "
+"      bb bb   bbb   "
+"       bbb     bb   "
+"        bb     bb   "
+"             bbbb   "
+
+[yellow-worrior-walk]
+
+"            yyy     "
+"           r yyy    "
+"             yyy  y "
+"          yyyyy     "
+"            yyy yy  "
+"            yyyyyyy "
+"           yyrryryy "
+"  y y     yyyrryry  "
+" ryryrrrrrrrrrryry  "
+"  y y   rrrrrryyyy  "
+"          yyyyy yy  "
+"            yyyy    "
+"           yyyyy    "
+"          yyyyyy    "
+"         yyy  yy    "
+"        yyy   yyy   "
+"        yy     yy   "
+"      yyyy   yyyy   "
+
+"            yyy     "
+"           r yyy    "
+"             yyy  y "
+"          yyyyy     "
+"            yyy yy  "
+"            yyyyyyy "
+"           yyrryryy "
+"  y y     yyyrryry  "
+" ryryrrrrrrrrrryry  "
+"  y y   rrrrrryyyy  "
+"          yyyyy yy  "
+"           yyyy     "
+"            yy      "
+"            yy      "
+"            yy      "
+"            yy      "
+"            yy      "
+"          yyyy      "
+
+"            yyy     "
+"           r yyy    "
+"             yyy  y "
+"          yyyyy     "
+"            yyy yy  "
+"            yyyyyyy "
+"           yyrryryy "
+"  y y     yyyrryry  "
+" ryryrrrrrrrrrryry  "
+"  y y   rrrrrryyyy  "
+"          yyyyy yy  "
+"           yyyy     "
+"            yyyy    "
+"            yyyyy   "
+"           yy yyy   "
+"           yy  yyy  "
+"           yy    y  "
+"         yyyy  yyy  "
+
+[yellow-worrior-shoot]
+
+"             yyy    "
+"            r yyy r "
+"              yyy   "
+"           yyyyy    "
+"   y         yyy yy "
+" rr          yrryyy "
+"  yy  y y   yyyrryy "
+" yyyyryryrrrrrrrryy "
+" ryy  y y  rrrrryyy "
+"            yyyyyyy "
+"            yyyyyyy "
+"           yyyyyy   "
+"          yyyyyyy   "
+"     y   yyy yyy    "
+"      y yyy  yyy    "
+"      yyyy    yyy   "
+"       yy      yy   "
+"             yyyy   "
+
+" r r   b      yyy   "
+"  ryy        r yyyr "
+" ryyyy         yyy  "
+"  yyyy      yyyyy   "
+" r    ry      yyyy  "
+"      yry      yyyy "
+"    b  yrr    yyryy "
+"         rrr yyrrry "
+"  r       rrrrrrryy "
+"            rrrryyy "
+"            yyyyyyy "
+"    y    yyyyyyyyy  "
+"     y  yyyyyyyyyy  "
+"     yyyyy     yyy  "
+"      yy       yyy  "
+"              yyy   "
+"              yyy   "
+"           yyyyy    "
+
+"  b   y       yyy   "
+"             r yyyr "
+" y r           yyy  "
+"   yy  r    yyyyy   "
+"  yyyy        yyy y "
+" r yyy        yyyyy "
+"  b   ryr    yyyryy "
+"      yrrrrr yyrrry "
+"        rrrrrrrrryy "
+"           rrrrryyy "
+"            yyyyyyy "
+"          yyyyyyy   "
+"     y   yyyyyyyy   "
+"      y yyy   yyy   "
+"      yyyy    yyy   "
+"       yy     yy    "
+"              yy    "
+"           yyyyy    "
+
+"             yyy    "
+"   y        r yyy r "
+"     r        yyy   "
+"           yyyyy    "
+"   y         yyy yy "
+" rr          yrryyy "
+"  yy  y y   yyyrryy "
+" yyyyryryrrrrrrrryy "
+" ryy  y y  rrrrryyy "
+"            yyyyyyy "
+"  b         yyyyyyy "
+"          yyyyyyy   "
+"          yyyyyyy   "
+"         yyy  yyy   "
+"      yy yy   yyy   "
+"       yyy     yy   "
+"        yy     yy   "
+"             yyyy   "
+
+[burwor-walk]
+
+"                b   "
+"               bbb  "
+"               bbb  "
+"           b   bbbb "
+"     bbbbbb    bbbb "
+"    bbrrbbb b  bbb  "
+" bbbbrrrbbbb   bbb  "
+" bbbbbbbbbbbb  bb   "
+" bbbbbbbbbb    b    "
+"  bbbb  bbb   b     "
+"        bbb  b      "
+"   bbb   bbbb    bb "
+"   bbbb  bbbbb bbbb "
+"    bbbbbbbbbbbbbb  "
+"    bbb bbbbbb bbb  "
+"     bb  bbbbb bb   "
+"      bb       b    "
+"   bbbbbb     bbbbb "
+
+"                 bb "
+"     bbbbbbb    bb  "
+"    bbrrbbb    bbbb "
+" bbbbrrrbbbbb  bbbb "
+" bbbbbbbbbbb    bbb "
+"  b b bbbbbbb  bbb  "
+" bbbbbbbbbb    bb   "
+"  bbbb  bbbb  bb    "
+"        bbb   b     "
+"        bbbb b      "
+"   bbbbbbbbbbbb     "
+"  bbbbbbbbbbbbbb    "
+"   bbb  bbbbbbbbb   "
+"    bb       bbbb   "
+"     bb       bb    "
+"  bbbbbb       b    "
+"              bbb   "
+"                 bb "
+
+"     bbbbbbb   bbb  "
+"    bbrrbbb   bbbbb "
+" bbbbrrrbbbbb bbb   "
+" bbbbbbbbbbb  bb    "
+"  b b bbbbbbb bb    "
+"      bbbbb    bb   "
+"  bbbb  bbbb   bb   "
+"        bbb   b     "
+"       bbbbb b      "
+"     bbbbbbbbbb     "
+"   bbbbbbbbbbbbbb   "
+"  bbbb        bbbb  "
+"   bb          bb   "
+"    bb        bb    "
+"   bbbb      bbbb   "
+"  b              b  "
+" b                b "
+"                    "
+
+[burwor-shoot]
+
+"                b   "
+"               bbb  "
+"            b  bbb  "
+"      bbbbbb   bbbb "
+"     bbrrbbb b bbbb "
+"  bbbbrrrbbbb  bbbb "
+"  bbbbbbbbbbb  bbb  "
+"  rbrbrbbbbbbb bbb  "
+" rbbbbbbbbbb   bb   "
+"   bbbb  bbb   b    "
+" r       bbbb b     "
+"   bbb   bbbbb   bb "
+"   bbbb  bbbbb bbbb "
+"    bbbbbbbbbbbbbb  "
+"    bbb bbbbbb bbb  "
+"     bb  bbbbb bb   "
+"      bb       b    "
+"   bbbbbb     bbbbb "
+
+"               b    "
+"               bb   "
+"            b  bbb  "
+"      bbbbbb   bbbb "
+"     bbrrbbb b bbbb "
+"  bbbbrrrbbbb  bbbb "
+"  bbbbbbbbbbb  bbb  "
+"  rbrbbbbbbbbb bbb  "
+" rrrrrrbbbbb   bb   "
+"   bbbb  bbb   b    "
+" r       bbbb b     "
+"   bbb   bbbbb   bb "
+"   bbbb  bbbbb bbbb "
+"    bbbbbbbbbbbbbb  "
+"  r bbb bbbbbb bbb  "
+"     bb  bbbbb bb   "
+"      bb       b    "
+" r bbbbbb     bbbbb "
+
+"       bbbbbb    b  "
+"      bbrrbb    bbb "
+"   bbbbrrrbbbb bbbb "
+"   bbbbbbbbbb  bbbb "
+" r  brbrbbbbbb bbbb "
+"  rrrrrrrbbb   bbbb "
+" rryrrrrbbbbb  bbb  "
+"  y bbbb bbb   bb   "
+"         bbbb bb    "
+" r     bbbbbbbb     "
+"   bbbbbbbbbbbb     "
+"  bbbbbbbbbbbbbb    "
+"   bbb  bbbbbbbbb   "
+" y  bb       bbbb   "
+"     bb       bb    "
+"  bbbbbb       b    "
+"         r    bbb   "
+"      r          bb "
+
+"        bbbbbb    b "
+"       bbrrbb    bb "
+"    bbbbrrrbbbb bbb "
+"    bbbbbbbbbb  bbb "
+" y   brbrbbbbbb bbb "
+"  rrrrrrrrbbb   bbb "
+" rrryrrrrbbbbb  bb  "
+"   y bbbb bbb  bb   "
+"          bbbbbb    "
+"      bbbbbbbbb     "
+"    bbbbbbbbbbbbb   "
+"   bbbbb      bbbb  "
+"    bb         bb   "
+"     bb       bb    "
+"    bbbb     bbbb   "
+"   b       r     b  "
+"  b  y            b "
+"         r          "
+
+[garwor-walk]
+
+"               rr   "
+"       yyyyy    rrr "
+"      yyyyyyy    rr "
+"    yyyy  yyyy    y "
+"  yyyyyyb yyyyy   y "
+"  yyyyyyyyyyyyyy  y "
+"    yryryyyyyyyy  y "
+"  rrrrrryyyyyyyyy y "
+" r yryryy yyyyyyy y "
+"    yyyy yyyyyyyy y "
+"         yyyyyyyyyy "
+"        yyyyyyyyyyy "
+"      yyyyyyyyyyyy  "
+"     y   yyyyyyyy   "
+"          yyyyy     "
+"          yyy  y    "
+"          yy   y    "
+"        yyy   yy    "
+
+"      yyyyy      rr "
+"     yyyyyy    rrr  "
+"   yyyy  yyy   rr   "
+" yyyyyyb yyyy  y    "
+" yyyyyyyyyyyy  y    "
+"   yryryryyyyy yyyy "
+"   rrrrrryyyyy    y "
+"  yryryryyyyyyy   y "
+"   yyyyyyyyyyyyy yy "
+"       yyyyyyyyy y  "
+"       yyyyyyyyyyy  "
+"       yyyyyyyyyyy  "
+"      y yyyyyyyyy   "
+"     y  yyyyyyyy    "
+"         yyyyy      "
+"          yy  yyy   "
+"           y    y   "
+"         yyy        "
+
+"       yyyyy    rrr "
+"      yyyyyy   rrr  "
+"    yyyy  yyy  rrr  "
+"  yyyyyyb yyyy  y   "
+"  yyyyyyyyyyyy  yyy "
+"    yryryryyyyy   y "
+"  rrrrrrrryyyyy   y "
+" r yryryryyyyyyy  y "
+"    yyyyyyyyyyyy  y "
+"        yyyyyyyyy y "
+"        yyyyyyyyyyy "
+"       yyyyyyyyyyyy "
+"         yyyyyyyyy  "
+"          yyyyyyy   "
+"         yyyyyy     "
+"        yy  yy      "
+"         yy  y      "
+"          y yy      "
+
+[garwor-shoot]
+
+"               rr   "
+"        yyyyy   rrr "
+"       yyyyyyy   rr "
+"     yyyy  yyyy   y "
+"   yyyyyyb yyyyy  y "
+" b yyyyyyyyyyyyyy y "
+"    ryryryyyyyyyy y "
+"  rrrrrrryyyyyyyyy  "
+" y  rryryy yyyyyyy  "
+"    yyyyy yyyyyyyyy "
+"  r       yyyyyyyyy "
+"         yyyyyyyyyy "
+"       yyyyyyyyyyy  "
+"      y   yyyyyyyy  "
+"           yyyyy    "
+"           yyy  y   "
+"           yy   y   "
+"         yyy   yy   "
+
+"        yyyyy   r   "
+"       yyyyyy  rrr  "
+"     yyyy  yyy rrr  "
+"   yyyyyyb yyyy rr  "
+" r yyyyyyyyyyyy y   "
+"     yryryryyyyy y  "
+" by  rrrrrryyyyy  y "
+" yyrrrrrrryyyyyyy y "
+" ryb rrryyyyyyyyy y "
+" yy  yyyyyyyyyyyyyy "
+"  b      yyyyyyyyyy "
+"         yyyyyyyyyy "
+"        y yyyyyyyyy "
+"       y  yyyyyyyy  "
+"           yyyyy    "
+"            yy  yyy "
+"             y    y "
+"           yyy      "
+
+"        yyyyy   rrr "
+"       yyyyyy  rrr  "
+" r   yyyy  yyy rrr  "
+"   yyyyyyb yyyyrr   "
+" y yyyyyyyyyyyy y   "
+" b   yryryryyyyy y  "
+" bb rrrrrrryyyyy  y "
+" yrrrrrrrryyyyyyy y "
+"  yb rrryyyyyyyyy y "
+" yr  yyyyyyyyyyyyyy "
+" rr      yyyyyyyyyy "
+"  ryy    yyyyyyyyyy "
+"   yb   y yyyyyyyyy "
+"       y  yyyyyyyy  "
+"           yyyyy    "
+"            yy  yyy "
+"             y    y "
+"           yyy      "
+
+"        yyyyy  rr   "
+" r     yyyyyy   rrr "
+"     yyyy  yyy   rr "
+"   yyyyyyb yyyy   y "
+" b yyyyyyyyyyyy   y "
+"     yryryryyyyy  y "
+"  rrrrrrrrryyyyy  y "
+"   rrrrrrryyyyyyy y "
+" y   rrryyyyyyyyy y "
+"   b yyyyyyyyyyyy y "
+" r       yyyyyyyyyy "
+"       yyyyyyyyyyyy "
+"    b    yyyyyyyyy  "
+"          yyyyyyy   "
+"         yyyyyy     "
+"        yy  yy      "
+"         yy  y      "
+"          y yy      "
+
+[thorwor-walk]
+
+"                rr  "
+"      yy       rr   "
+"     y  r     rrr   "
+"    y  rrr    r     "
+"      rrrrr   rr    "
+"     rr rrrr   r    "
+"    rr  rrrr   rrr  "
+"    rr brrrrr    r  "
+"  rrrrrrrrrrrr   rr "
+" rrrrrrrrrrrrrrrrrr "
+"    rrrrrrrrrrrrrr  "
+" rr    rrrrrrrrrrr  "
+" rrrrrrrrrrrrrrrr   "
+"    rrrr  r  r  r   "
+"          r  r  r   "
+"         rr rr rr   "
+"         r  r  r    "
+"        bb bb bb    "
+
+"                rr  "
+"      yy        r   "
+"     y  r       r   "
+"    y  rrr      rr  "
+"      rrrrr      r  "
+"     rr rrrr     r  "
+"    rr  rrrr     r  "
+"   rrr brrrrr    rr "
+" rrrrrrrrrrrrr   rr "
+" rr  rrrrrrrrrrrrrr "
+"   b  rrrrrrrrrrrr  "
+"       rrrrrrrrrrr  "
+" r b rrrrrrrrrrrr   "
+" rrrrrrrr r  r  r   "
+"   rrrr   r  r  r   "
+"          r  r  r   "
+"          r  r  r   "
+"         bb bb bb   "
+
+"    y y    rrrr     "
+"       y      rrr   "
+"        r       r   "
+"       rrr      r   "
+"    rrrrrrr     r   "
+"     rr rrrr    rr  "
+"    rr  rrrr     r  "
+"  rrrr brrrrr    rr "
+" rr  rrrrrrrrr   rr "
+" r b  rrrrrrrrrrrrr "
+"   b   rrrrrrrrrrr  "
+"       rrrrrrrrrrr  "
+"      rrrrrrrrrrr   "
+" r b  rrr r  r  r   "
+" rr  rrr  r  r  r   "
+"  rrrrr   rr rr rr  "
+"           r  r  r  "
+"          bb bb bb  "
+
+[thorwor-shoot]
+
+"          yyy     r "
+"         rr  yy   r "
+"        rrrr   yyr  "
+"       rr rrr  rr   "
+"   rrrrr  rrrr  rr  "
+"  r   r  brrrr    r "
+" r b   rrrrrrr    r "
+"       rrrrrrr    r "
+"   yyyyyrrrrrrr  rr "
+"     yyyrrrrrrrrrrr "
+" r b   rrrrrrrrrrr  "
+"  r   rrrrrrrrrrrr  "
+"  rr rrr rrrrrrrr   "
+"    rrr   r  r  r   "
+"          r  r  r   "
+"         rr rr rr   "
+"         r  r  r    "
+"         bb bb bb   "
+
+"            yy   r  "
+"        rrrr  y  r  "
+"    rrrrrr rr  yr   "
+"  rr rrr   rr   y   "
+"    b rr brrr  ry   "
+" y  b  rrrrrrr r y  "
+" yy     rrrrrr  r   "
+"  yyyyyyrrrrrrr  r  "
+"    yyyyrrrrrrr   r "
+" r b  yrrrrrrrrr rr "
+"  r   rrrrrrrrrrrrr "
+"  rr rrrrrrrrrrrrrr "
+"    rrr  rrrrrrrrr  "
+"          r  rr rr  "
+"          rr  r  r  "
+"           rr rr rr "
+"            r  r  r "
+"           bb bb bb "
+
+"            yy   r  "
+"        rrrr  y rrr "
+"    rrrrrr rr y r r "
+"  rr rrr   rr y r   "
+"    b rr brrr y r   "
+" yy    rrrrrrr y r  "
+"   yy   rrrrrr  yr  "
+"    yyyyrrrrrrr  r  "
+"     yyyrrrrrrr  r  "
+" r b   rrrrrrrrr rr "
+"  r   rrrrrrrrrrrrr "
+"  rr rrrrrrrrrrrrrr "
+"    rrr  rrrrrrrrr  "
+"           r  r  r  "
+"           r  r  r  "
+"          rr rr rr  "
+"          r  r  r   "
+"          bb bb bb  "
+
+"            y   rrr "
+"        rrrr y rr r "
+"    rrrrrr rr yr  r "
+"  rr rrr   rr  y rr "
+" y  b rr brrr  yr   "
+" yy    rrrrrrr y r  "
+"  yyyy  rrrrrr    r "
+"    yyy rrrrrrr   r "
+"     yyyrrrrrrr   r "
+" r b  yrrrrrrrrr rr "
+"  r   rrrrrrrrrrrrr "
+"  rr rrrrrrrrrrrrrr "
+"    rrr  rrrrrrrrr  "
+"          r  rr rr  "
+"          rr  r  r  "
+"           rr rr rr "
+"            r  r  r "
+"           bb bb bb "
+
+[worluk-walk]
+
+"      bb     bb  yy "
+" yy     b   b   yyy "
+" yyy   yryyyry  yyy "
+" yyyy yrrryrrryyyyy "
+" yyyyyrrrryrrrryyyy "
+" bbyyy yryyyryyyyyb "
+"  bbyyy  yyy  yyybb "
+"  bybbyy byb yybb b "
+"  b  ybybbbbbyby  b "
+"   b   bbbbbbby   b "
+"    b   bbbbb    b  "
+"        bbbbb       "
+"        bbbbb       "
+"      bbbbbbbbb     "
+"     b  bbbbb  b    "
+"     b   bbb   b    "
+"     b    b    b    "
+"   bbb         bbb  "
+
+"       b    b       "
+"       b   b        "
+"      yryyyry       "
+"  y  yrrryrrry      "
+" bby rrrryrrrr  yyy "
+" ybyy yryyyry  yyyy "
+" ybbyy  yyy  yyyybb "
+" ybybyy byb yybbbby "
+" ybyybybbbbbybyybby "
+" yybyybbbbbbbyyybyy "
+"  yybyybbbbbyyybyy  "
+"   yyy bbbbb yyyy   "
+"       bbbbb        "
+"    bbbbbbbbb       "
+"    b  bbbbb b      "
+"     b  bbb   b     "
+"      b  b     b    "
+"    bbb        bbb  "
+
+"                    "
+"         b   b      "
+"        b   b       "
+"       yryyyry      "
+"      yrrryrrry     "
+"      rrrryrrrr     "
+"       yryyyry      "
+"    yyy  yyy  yyy   "
+" bbbbbby byb ybbbbb "
+"  byyyybbbbbbbyybb  "
+"  ybyyyybbbbbyybyyy "
+"  yybyy bbbbb byyyy "
+" yyyyy  bbbbb  yyyy "
+" yyyybbbbbbbbbbbyyy "
+" yyy b  bbbbb  byyy "
+" yy   b  bbb  b  yy "
+"       b  b  b      "
+"     bbbb   bbbb    "
+
+[wizard-walk]
+
+"         bbbb       "
+"       bbbbb        "
+"      b    b        "
+"      by y bbb      "
+"      bb  bbbbb     "
+"     bbbb bbbbbbb   "
+"    bb  bbbbb   bb  "
+"    b    bbbb    bb "
+"   bb    bbbbb    r "
+" rr      bbbbb    r "
+"        bbbbbb      "
+"       bbbbbbb      "
+"     bbbbbbbbbb     "
+"     bbbbbbbbbb     "
+"      bbbbbbbbbb    "
+"      bbbbbbbbbbb   "
+"       bbbbbbbbbbb  "
+"      bbbbbbbbbbbb  "
+
+"      bbbb          "
+"     b  bbb         "
+"     by ybb         "
+"     bb  bbbb       "
+"      bb bbbbb      "
+"     bbbbbbb bb     "
+"      b bbbb  bb    "
+"     b   bbbb  bb   "
+"    bb   bbbbb  r   "
+"  rr    bbbbbb  r   "
+"       bbbbbbb      "
+"      bbbbbbb       "
+"     bbbbbbbbb      "
+"      bbbbbbbbb     "
+"       bbbbbbbbb    "
+"        bbbbbbbbb   "
+"        bbbbbbbb    "
+"      bbbbb         "
+
+"         bbb        "
+"      bbbbb         "
+"     b bbbb         "
+"     by bbb         "
+"     bb  bbbb       "
+"      bb bbbbb      "
+"      bbbbbb bb     "
+"        bbbbb bb    "
+"       b bbbbbbb    "
+"      bb bbbbbr     "
+"    rr  bbbbbrr     "
+"       bbbbbbbb     "
+"      bbbbbbbb      "
+"      bbbbbbbb      "
+"       bbbbbb       "
+"       bbbbbb       "
+"      bbbbbbbb      "
+"      bbbbbbbb      "
+
+"       bbbb         "
+"      b  bbb        "
+"      by ybb        "
+"      bb  bbb       "
+"       bb bbbbb     "
+"       bbbbbbbbb    "
+"       bbbbbb  bb   "
+"      bb bbbb   b   "
+"     bb   bbbb  bb  "
+"   rr   bbbbbb   r  "
+"      bbbbbbbb   r  "
+"     bbbbbbbbb      "
+"     bbbbbbbb       "
+"      bbbbbbb       "
+"      bbbbbbb       "
+"       bbbbbbb      "
+"     bbbbbbbbb      "
+"         bbbbb      "
+
+[wizard-shoot]
+
+"         bbbb       "
+"        b   bb      "
+"   r    by ybb      "
+" rrrr   bb  b       "
+"    rb   b  b  rrrr "
+"    bb bbbb bbb rrb "
+"    bbbbbbbbbbbbrbb "
+"     bbbbbbbb bbbb  "
+"         bbbb  bb   "
+"         bbbb       "
+"        bbbbb       "
+"       bbbbbbb      "
+"      bbbbbbbb      "
+"     bbbbbbbbb      "
+"     bbbbbbbbbb     "
+"     bbbbbbbbbb     "
+"    bbbbbbbbbbb     "
+"   bbbbbbbbbbbbb    "
+
+"           bbb      "
+"          bb bbb    "
+"          by ybbb   "
+"          b   bb    "
+" rrrr  bbbbb  b     "
+"    rr bbbbb bbbb   "
+"     rr   bbrrrrrb  "
+"     rr   bbbbb rrr "
+"          bbbb   rr "
+"          bbb       "
+"         bbbbb      "
+"        bbbbbb      "
+"       bbbbbbb      "
+"       bbbbbb       "
+"       bbbbbb       "
+"      bbbbbbbb      "
+"      bbbbbbbbb     "
+"    bbbbbbbbbbbb    "
+
+"             bbbb   "
+"            bbbbbb  "
+"    rrrbb    ybbbbb "
+" yy   rbbbb    bbb  "
+"    rr   bbbbbbbb   "
+" yyy rrbbbbbbbbbbb  "
+"      rbb    bbbbb  "
+"       b      bbbb  "
+"              bbbb  "
+"             bbbb   "
+"           bbbbbb   "
+"          bbbbbbb   "
+"         bbbbbbb    "
+"         bbbbbbb    "
+"         bbbbbbb    "
+"        bbbbbbbbb   "
+"        bbbbbbbbbb  "
+"      bbbbbbbbbbbbb "
+
+[worrior-flash]
+
+"         rrbbbrr    "
+"         ryrbbbr    "
+"        rrrrbbbr    "
+"        rbbbbbrrrr  "
+"        rrrbbbrbbr  "
+"          rbbbbbbb  "
+" r r     rbbyybybb  "
+"rbrbrrrrrbbbyybybr  "
+"ybybyyyyyyyyyybbbr  "
+"rbrbrrryyyyyybbbbr  "
+" r r  rrrbbbbbrbbr  "
+"         rbbbbrrrr  "
+"         rbbbbbr    "
+"        rbbbbbbr    "
+"       rbbbrrbbr    "
+"      rbbbr rbbbr   "
+"    rrrbbr  rrbbr   "
+"    rbbbbr rbbbbr   "
+
+"         rryyyrr    "
+"         rbryyyr    "
+"        rrrryyyr    "
+"        ryyyyyrrrr  "
+"        rrryyyryyr  "
+"          ryyyyyyy  "
+" r r     ryybbybyy  "
+"ryryrrrrryyybbybyr  "
+"bybybbbbbbbbbbyyyr  "
+"ryryrrrbbbbbbyyyyr  "
+" r r  rrryyyyyryyr  "
+"         ryyyyrrrr  "
+"         ryyyyyr    "
+"        ryyyyyyr    "
+"       ryyyrryyr    "
+"      ryyyr ryyyr   "
+"    rrryyr  rryyr   "
+"    ryyyyr ryyyyr   "
+
+[blue-worrior-death]
+
+"                    "
+"              b     "
+"b b          bb     "
+"bybyyyyyy    bb y   "
+"b b   yyy    bbbbb  "
+"           b   bb   "
+"        y   y  r    "
+"       rbb y   b    "
+"             r y    "
+"         b b  b b   "
+"        b ry   y    "
+"     bb  y   yb r   "
+"    bbb    b        "
+"   bbb         bbb  "
+"   bb         bbbb  "
+" bbbb         bb b  "
+"                 b  "
+"                    "
+
+[yellow-worrior-death]
+
+"              y     "
+"y y          yy     "
+"ybybbbbbb    yy b   "
+"y y   bbb    yyyyy  "
+"         y    yyyy  "
+"           y   yy   "
+"        b   b  r    "
+"       ryy b   y    "
+"             r b    "
+"         y y  y y   "
+"        y rb   b    "
+"     yy  b   by r   "
+"    yyy    y        "
+"   yyy         yyy  "
+"   yy         yyyy  "
+" yyyy         yy y  "
+"                 y  "
+"                    "
+
+[common-death]
+
+"      y  b          "
+" b r   y   y b      "
+"    y b r    r      "
+"    r  b  b         "
+"  y           r     "
+"    b     by        "
+"r     ry   r b r    "
+"   r    b y         "
+"   y   b   b y      "
+"b     b  b     b    "
+"         y  y       "
+" r   y r      r     "
+"   b  b  y  r b     "
+" y r   y   r   b    "
+"   b y   r   r b    "
+"     r  y   b b     "
+"      b   y         "
+"                    "
+
+"         r   y      "
+"     y      b       "
+" y  r    b    y     "
+"      b     y   b   "
+"    b        y      "
+" r       b   r      "
+"    y      y     b  "
+"b     b  r     r    "
+"   r           y    "
+"        y           "
+" r   y   r     b    "
+"   b   y      r  b  "
+"   b    y  b    y   "
+"b     r       r     "
+"   y b   b     r    "
+"       r      y     "
+"    b      b        "
+"       r            "
+
+[explosion]
+
+"                    "
+"                    "
+"                    "
+"    r     b         "
+"r   rr r            "
+" rrrrrrr  r         "
+"  rrrrrrrrr         "
+"  rrrbrrbrrr        "
+"rrrrbbbbbrr         "
+"rrrbbbbbbrr         "
+" rrrrrbbbrr         "
+"  rr rrrrr          "
+"b r   rrr  b        "
+"      rrr           "
+"       r            "
+"                    "
+"                    "
+"                    "
+
+"   b                "
+"    b               "
+"    bbb             "
+"     bb   b         "
+"     bbbbbb     r   "
+"     brbbbb  bb     "
+"    bbrrrbbbbbbb    "
+"    bbrrrrrrrrbb    "
+"r  bbrrrrrrrrrb     "
+" bbbbrrrrrrrrbb     "
+" bbbrrrrrrrrrbb     "
+"  bbrrrrrrrrrrbb    "
+"  bbrrbbrrrbrrb     "
+"    bbbbbbbbbbb     "
+"  bb bb  bb b bbb   "
+"  b         b   b   "
+"bb          b       "
+"                    "
+
+"         y          "
+"y       y       y   "
+" y     y       y    "
+"  y    y      y     "
+"   yy yyy yy  y     "
+"    yyrrrryyy y     "
+"   yyrrrrrryyy      "
+"   yyrrrrrrryy   y  "
+"  yyrrrrrrrryy      "
+"  yyrrrrrrrryy      "
+"  yyrrrrrrrryy      "
+"  yyyrrrrrrrryy     "
+" y  yryyyrrrry      "
+"y   yy  yyrryyy     "
+"         yyyy yyy   "
+"         y      y   "
+"        y           "
+"       y            "
diff --git a/dow.cabal b/dow.cabal
--- a/dow.cabal
+++ b/dow.cabal
@@ -1,47 +1,47 @@
-Name:                dow
-Version:             0.2.5
-Cabal-Version:       >= 1.2
-Synopsis:            Dungeons of Wor
-Category:            game, reactivity, FRP
-Description:
-
-  Dungeons of Wor is a homage to the classic arcade game, Wizard of
-  Wor.  It uses the artwork and levels from the Astrocade version, but
-  the gameplay mechanics differ from the original in several ways.
-  .
-  This game is also an experiment in functional reactive programming,
-  so it might be a useful resource to anyone interested in this topic.
-  It was coded using the simple version of Elerea, which provides
-  discrete streams as first-class values.
-
-Author:              Patai Gergely
-Maintainer:          Patai Gergely (patai.gergely@gmail.com)
-Copyright:           (c) 2010-2011, Patai Gergely
-License:             BSD3
-License-File:        LICENSE
-Stability:           experimental
-Build-Type:          Simple
-Extra-Source-Files:
-  src/Actor.hs
-  src/Game.hs
-  src/GraphUtils.hs
-  src/HighScore.hs
-  src/Level.hs
-  src/Render.hs
-  src/Sprites.hs
-  src/Text.hs
-  src/Utils.hs
-  src/Vector.hs
-
-Data-Files:
-  README
-  CHANGES
-  data/charset.txt
-  data/levels.txt
-  data/sprites.txt
-
-Executable dow
-  HS-Source-Dirs:    src
-  Main-IS:           Main.hs
-  Build-Depends:     base >= 4 && < 5, elerea >= 2.5.0, OpenGL >= 2.4, GLFW >= 0.5.2 && < 0.5.3, array, directory, mersenne-random
-  GHC-Options:       -O2 -fno-warn-deprecated-flags
+Name:                dow
+Version:             0.2.6
+Cabal-Version:       >= 1.6
+Synopsis:            Dungeons of Wor
+Category:            game, reactivity, FRP
+Description:
+
+  Dungeons of Wor is a homage to the classic arcade game, Wizard of
+  Wor.  It uses the artwork and levels from the Astrocade version, but
+  the gameplay mechanics differ from the original in several ways.
+  .
+  This game is also an experiment in functional reactive programming,
+  so it might be a useful resource to anyone interested in this topic.
+  It was coded using the simple version of Elerea, which provides
+  discrete streams as first-class values.
+
+Author:              Patai Gergely
+Maintainer:          Patai Gergely (patai.gergely@gmail.com)
+Copyright:           (c) 2010-2011, Patai Gergely
+License:             BSD3
+License-File:        LICENSE
+Stability:           experimental
+Build-Type:          Simple
+Extra-Source-Files:
+  src/Actor.hs
+  src/Game.hs
+  src/GraphUtils.hs
+  src/HighScore.hs
+  src/Level.hs
+  src/Render.hs
+  src/Sprites.hs
+  src/Text.hs
+  src/Utils.hs
+  src/Vector.hs
+
+Data-Files:
+  README
+  CHANGES
+  data/charset.txt
+  data/levels.txt
+  data/sprites.txt
+
+Executable dow
+  HS-Source-Dirs:    src
+  Main-IS:           Main.hs
+  Build-Depends:     base >= 4 && < 5, elerea == 2.9.*, OpenGL >= 2.4, GLFW >= 0.5.2 && < 0.5.3, array, directory, mersenne-random
+  GHC-Options:       -O2 -fno-warn-deprecated-flags
diff --git a/src/Actor.hs b/src/Actor.hs
--- a/src/Actor.hs
+++ b/src/Actor.hs
@@ -1,117 +1,117 @@
-module Actor where
-
-import Data.Array
-import Data.List
-import Data.Maybe
-import Graphics.Rendering.OpenGL hiding (position)
-
-import Level
-import Sprites
-import Vector
-
-data Skin = Skin
-            { walkAnimation :: [TextureObject]
-            , shootAnimation :: [TextureObject]
-            , deathAnimation :: [TextureObject]
-            }
-
-data ActorType = BlueWorrior | YellowWorrior | Burwor | Garwor | Thorwor | Worluk | Wizard
-               deriving (Eq, Ord, Enum, Ix, Show)
-
-data Action = Entering Direction Bool | Walking | Shooting | KilledBy ActorType deriving Eq
-
-data Actor = Actor
-             { actorType :: ActorType
-             , position :: Vec
-             , facing :: Direction
-             , action :: Action
-             , animation :: [TextureObject]
-             , skin :: Skin
-             , speed :: Int
-             , animSpeed :: Int
-             , tick :: Int
-             }
-
-mkActor :: Array ActorType Skin -> ActorType -> Vec -> Actor
-mkActor skins atype pos =
-  Actor { actorType = atype
-        , position = pos
-        , facing = East
-        , action = Walking
-        , animation = walkAnimation (skins ! atype)
-        , skin = skins ! atype
-        , speed = 1
-        , animSpeed = 2
-        , tick = 0
-        }
-
-createSkins :: SpriteStore -> Array ActorType Skin
-createSkins sprites = array (BlueWorrior,Wizard)
-  [(BlueWorrior,
-    Skin { walkAnimation = cycle (anim "blue-worrior-walk")
-         , shootAnimation = anim "blue-worrior-shoot"
-         , deathAnimation = concat (replicate 5 (anim "worrior-flash")) ++
-                            anim "blue-worrior-death" ++ anim "common-death"
-         }
-   )
-  ,(YellowWorrior,
-    Skin { walkAnimation = cycle (anim "yellow-worrior-walk")
-         , shootAnimation = anim "yellow-worrior-shoot"
-         , deathAnimation = concat (replicate 5 (anim "worrior-flash")) ++
-                            anim "yellow-worrior-death" ++ anim "common-death"
-         }
-   )
-  ,(Burwor,
-    Skin { walkAnimation = cycle (anim "burwor-walk")
-         , shootAnimation = anim "burwor-shoot"
-         , deathAnimation = anim "explosion" ++ anim "common-death"
-         }
-   )
-  ,(Garwor,
-    Skin { walkAnimation = cycle (anim "garwor-walk")
-         , shootAnimation = anim "garwor-shoot"
-         , deathAnimation = anim "explosion" ++ anim "common-death"
-         }
-   )
-  ,(Thorwor,
-    Skin { walkAnimation = cycle (anim "thorwor-walk")
-         , shootAnimation = anim "thorwor-shoot"
-         , deathAnimation = anim "explosion" ++ anim "common-death"
-         }
-   )
-  ,(Worluk,
-    Skin { walkAnimation = cycle (anim "worluk-walk")
-         , shootAnimation = []
-         , deathAnimation = anim "explosion" ++ anim "common-death"
-         }
-   )
-  ,(Wizard,
-    Skin { walkAnimation = cycle (anim "wizard-walk")
-         , shootAnimation = anim "wizard-shoot"
-         , deathAnimation = []
-         }
-   )]
-  where anim name = maybe (error ("Cannot find animation " ++ name)) snd
-                    (find ((==name).fst) sprites)
-
-isDead :: Actor -> Bool
-isDead a = case action a of
-  KilledBy _ -> True
-  _          -> False
-
-isAlive :: Actor -> Bool
-isAlive = not . isDead
-
-justDied :: Actor -> Bool
-justDied Actor { action = KilledBy _, animation = [_], tick = 0 } = True
-justDied _ = False
-
-actorValue :: Actor -> Int
-actorValue a = case actorType a of
-  Burwor        -> 100
-  Garwor        -> 200
-  Thorwor       -> 500
-  Worluk        -> 1000
-  Wizard        -> 2500
-  BlueWorrior   -> 1000
-  YellowWorrior -> 1000
+module Actor where
+
+import Data.Array
+import Data.List
+import Data.Maybe
+import Graphics.Rendering.OpenGL hiding (position)
+
+import Level
+import Sprites
+import Vector
+
+data Skin = Skin
+            { walkAnimation :: [TextureObject]
+            , shootAnimation :: [TextureObject]
+            , deathAnimation :: [TextureObject]
+            }
+
+data ActorType = BlueWorrior | YellowWorrior | Burwor | Garwor | Thorwor | Worluk | Wizard
+               deriving (Eq, Ord, Enum, Ix, Show)
+
+data Action = Entering Direction Bool | Walking | Shooting | KilledBy ActorType deriving Eq
+
+data Actor = Actor
+             { actorType :: ActorType
+             , position :: Vec
+             , facing :: Direction
+             , action :: Action
+             , animation :: [TextureObject]
+             , skin :: Skin
+             , speed :: Int
+             , animSpeed :: Int
+             , tick :: Int
+             }
+
+mkActor :: Array ActorType Skin -> ActorType -> Vec -> Actor
+mkActor skins atype pos =
+  Actor { actorType = atype
+        , position = pos
+        , facing = East
+        , action = Walking
+        , animation = walkAnimation (skins ! atype)
+        , skin = skins ! atype
+        , speed = 1
+        , animSpeed = 2
+        , tick = 0
+        }
+
+createSkins :: SpriteStore -> Array ActorType Skin
+createSkins sprites = array (BlueWorrior,Wizard)
+  [(BlueWorrior,
+    Skin { walkAnimation = cycle (anim "blue-worrior-walk")
+         , shootAnimation = anim "blue-worrior-shoot"
+         , deathAnimation = concat (replicate 5 (anim "worrior-flash")) ++
+                            anim "blue-worrior-death" ++ anim "common-death"
+         }
+   )
+  ,(YellowWorrior,
+    Skin { walkAnimation = cycle (anim "yellow-worrior-walk")
+         , shootAnimation = anim "yellow-worrior-shoot"
+         , deathAnimation = concat (replicate 5 (anim "worrior-flash")) ++
+                            anim "yellow-worrior-death" ++ anim "common-death"
+         }
+   )
+  ,(Burwor,
+    Skin { walkAnimation = cycle (anim "burwor-walk")
+         , shootAnimation = anim "burwor-shoot"
+         , deathAnimation = anim "explosion" ++ anim "common-death"
+         }
+   )
+  ,(Garwor,
+    Skin { walkAnimation = cycle (anim "garwor-walk")
+         , shootAnimation = anim "garwor-shoot"
+         , deathAnimation = anim "explosion" ++ anim "common-death"
+         }
+   )
+  ,(Thorwor,
+    Skin { walkAnimation = cycle (anim "thorwor-walk")
+         , shootAnimation = anim "thorwor-shoot"
+         , deathAnimation = anim "explosion" ++ anim "common-death"
+         }
+   )
+  ,(Worluk,
+    Skin { walkAnimation = cycle (anim "worluk-walk")
+         , shootAnimation = []
+         , deathAnimation = anim "explosion" ++ anim "common-death"
+         }
+   )
+  ,(Wizard,
+    Skin { walkAnimation = cycle (anim "wizard-walk")
+         , shootAnimation = anim "wizard-shoot"
+         , deathAnimation = []
+         }
+   )]
+  where anim name = maybe (error ("Cannot find animation " ++ name)) snd
+                    (find ((==name).fst) sprites)
+
+isDead :: Actor -> Bool
+isDead a = case action a of
+  KilledBy _ -> True
+  _          -> False
+
+isAlive :: Actor -> Bool
+isAlive = not . isDead
+
+justDied :: Actor -> Bool
+justDied Actor { action = KilledBy _, animation = [_], tick = 0 } = True
+justDied _ = False
+
+actorValue :: Actor -> Int
+actorValue a = case actorType a of
+  Burwor        -> 100
+  Garwor        -> 200
+  Thorwor       -> 500
+  Worluk        -> 1000
+  Wizard        -> 2500
+  BlueWorrior   -> 1000
+  YellowWorrior -> 1000
diff --git a/src/Game.hs b/src/Game.hs
--- a/src/Game.hs
+++ b/src/Game.hs
@@ -1,292 +1,292 @@
-{-# LANGUAGE RecursiveDo #-}
-
-module Game where
-
-import Control.Applicative
-import Control.Monad
-import Control.Monad.Fix
-import Data.Array
-import Data.List
-import Data.Maybe
-import FRP.Elerea.Simple
-
-import Actor
-import GraphUtils
-import HighScore
-import Level
-import Sprites
-import Utils
-import Vector
-
-numberOfLives = 5
-
-data LevelState = LevelState
-                  { level :: Level
-                  , actors :: [Actor]
-                  , bullets :: [(ActorType,Vec)]
-                  , shooters :: [ActorType]
-                  }
-
-keySet1 = fst
-keySet2 = snd
-
-keyDir (True,_,_,_,_) = Just North
-keyDir (_,True,_,_,_) = Just South
-keyDir (_,_,True,_,_) = Just West
-keyDir (_,_,_,True,_) = Just East
-keyDir _              = Nothing
-
-keyShoot (_,_,_,_,s) = s
-
-keyAny k = keyShoot k || isJust (keyDir k)
-
-game highScore storeScore (renderGame,renderMenu) closeAction newActor levels keyPress = do
-  let firstTrue s = do
-        mask <- delay False =<< transfer False (||) s
-        return (liftA2 (&&) (not <$> mask) s)
-
-      mkGame 0 = playGame storeScore renderGame newActor levels keyPress 1
-      mkGame 1 = playGame storeScore renderGame newActor levels keyPress 2
-      mkGame _ = return (pure (void closeAction),pure True)
-
-  keys <- memo (keySet1 <$> keyPress)
-  (output,_) <- switcher . flip fmap highScore $ \score -> do
-    (menu,pick) <- displayMenu (renderMenu score) ["ONE PLAYER GAME","TWO PLAYER GAME","QUIT"] keys
-    picked <- firstTrue (keyShoot <$> keys)
-    gameSource <- generator (toMaybe <$> picked <*> (mkGame <$> pick))
-    fullOutput <- menu --> gameSource
-    return (fst =<< fullOutput,snd =<< fullOutput)
-
-  return output
-
-displayMenu renderMenu items keys = do
-  let val False = 0
-      val True  = 1
-
-  up <- edge ((==Just North) . keyDir <$> keys)
-  down <- edge ((==Just South) . keyDir <$> keys)
-  item <- transfer2 0 (\u d i -> (i + val d - val u) `mod` length items) up down
-
-  return ((renderMenu items <$> item,pure False),item)
-
-playGame storeScore renderFun newActor levels keyPress numPlayers = mdo
-  let startLevel level enemyCount = playLevel newActor keyPress level numPlayers lives' enemyCount
-      players = take numPlayers [YellowWorrior,BlueWorrior]
-
-      pickLevel cnt rnd = case () of
-        _ | cnt == 4         -> findLevel (=="arena")
-        _ | cnt < 8          -> findLevel ((=='b').head)
-        _ | cnt `mod` 6 == 1 -> findLevel (=="pit")
-        otherwise            -> findLevel ((=='w').head)
-        where findLevel p = pickOne (filter (p.levelName) levels)
-              pickOne xs = xs !! (rnd `mod` length xs)
-
-      accumScore player state prev = max 0 $ prev +
-                                     (sum . map killScore . actors) state -
-                                     10 * (length . filter (==player) . shooters) state
-        where killScore a = if justDied a && action a == KilledBy player then actorValue a else 0
-
-      accumLives player state prev = max 0 $ prev + (sum . map lifeLost . actors) state
-        where lifeLost a = if justDied a && actorType a == player then -1 else 0
-
-  levelNoise <- noise
-  (state,trigLevel) <- switcher (startLevel <$> (pickLevel <$> levelCount <*> levelNoise) <*> levelCount)
-  trigLevel' <- delay False trigLevel
-  levelCount <- transfer 1 (\win cnt -> if win then cnt+1 else cnt) trigLevel'
-  scores <- memo =<< (sequence <$> forM players (\t -> transfer 0 (accumScore t) state))
-  lives <- memo =<< (sequence <$> forM players (\t -> transfer numberOfLives (accumLives t) state))
-  lives' <- delay (replicate numPlayers numberOfLives) lives
-
-  gameOver <- memo (all (==0) <$> lives)
-
-  return (liftA2 (>>)
-          ((\c s -> when c (storeScore s)) <$> gameOver <*> scores)
-          (renderFun <$> state <*> levelCount <*> scores <*> lives)
-         ,gameOver
-         )
-
-playLevel newActor keyPress level numPlayers lives enemyCount = mdo
-  let mkEnemy etype = enemy (newActor etype) (if etype == Worluk then 2 else 1) level bullets
-
-      mkShot c plr = if c && canShoot
-                     then (:[]) <$> bullet (actorType plr) (position plr) (facing plr)
-                     else return []
-        where canShoot = case action plr of
-                Walking  -> True
-                Shooting -> True
-                _        -> False
-
-      spawnEnemies oldEnemies = concatMap (spawnEnemy (length oldEnemies == 1)) oldEnemies
-      spawnEnemy isLast enemy = if justDied enemy then
-                                    case actorType enemy of
-                                      Burwor  -> [mkEnemy Garwor <$> (position <$> head players)]
-                                      Garwor  -> [mkEnemy Thorwor <$> (position <$> head players)]
-                                      Thorwor -> if isLast then [mkEnemy Worluk <$> (position <$> head players)] else []
-                                      _       -> []
-                                else []
-
-      (lw,lh) = levelSize level
-      playerInit = take numPlayers [(YellowWorrior,keySet1,1),(BlueWorrior,keySet2,0)]
-
-  (players,bulletSources) <- fmap unzip $ forM (zip playerInit [0..]) $ \((worType,keySet,pix),lix) -> do
-    shoot <- edge (keyShoot . keySet <$> keyPress)
-
-    (player,_respawn) <- switcher . flip fmap lives $ \ls -> do
-      let (pedir,py,px) = entrances level !! pix
-          playerInit = (newActor worType (V (px*fieldSize) ((lh-py-1)*fieldSize)))
-                         { action = Entering pedir False
-                         , facing = [East,West] !! pix
-                         }
-          respawn plr = ls !! lix > 1 && null (animation plr)
-
-      if ls !! lix == 0
-        then return (pure (playerInit { animation = [] }),pure False)
-        else do plr <- transfer3 playerInit (movePlayer level) (keyDir . keySet <$> keyPress) shoot enemies'
-                return (plr, respawn <$> plr)
-
-    bulletSource <- generator (mkShot <$> shoot <*> player)
-    return (player,bulletSource)
-
-  newBullets <- memo (concat <$> sequence bulletSources)
-  bullets <- collection newBullets (notHitAnything level <$> enemies')
-  let shooters = fmap (map fst) . sequence =<< newBullets
-
-  initialEnemies <- replicateM enemyCount (mkEnemy Burwor (V (-3*fieldSize) (-3*fieldSize)))
-  spawnedEnemies <- generator (sequence <$> (sequence . spawnEnemies =<< enemies'))
-  enemySource <- delay initialEnemies spawnedEnemies
-  enemies <- collection enemySource (pure (not . null . animation))
-  enemies' <- delay [] enemies
-
-  return (LevelState level <$> (liftA2 (++) (sequence players) enemies) <*> bullets <*> shooters
-         ,null <$> enemies
-         )
-
-bullet src pos dir = fmap ((,) src) <$> stateful pos (+3*dirVec dir)
-
-enemy newActor moveSpeed level bullets (V playerX playerY) = mdo
-  let actorInit = (newActor (fromIntegral fieldSize*startPos)) { speed = moveSpeed, animSpeed = 4 }
-      startPos = if abs (startX-playerX `div` fieldSize) < 3 && abs (startY-playerY `div` fieldSize) < 3
-                 then V ((startX + lw `div` 2) `mod` lw) ((startY + lh `div` 2) `mod` lh)
-                 else V startX startY
-      (lw,lh) = levelSize level
-
-  startX <- (`mod` lw) <$> getRandom
-  startY <- (`mod` lh) <$> getRandom
-  startDir <- toEnum . (`mod` 4) <$> getRandom
-  dirNoise <- noise
-
-  actorInput <- startDir --> newDir level <$> dirNoise <*> actor'
-  actor <- transfer2 actorInit (moveEnemy level) actorInput bullets
-  actor' <- delay actorInit actor
-  return actor
-
-notHitAnything lev es (_,pos@(V px py)) =
-  (sy <  fieldMid-bs || North `elem` legals) &&
-  (sx <  fieldMid-bs || East  `elem` legals) &&
-  (sy > -fieldMid+bs || South `elem` legals) &&
-  (sx > -fieldMid+bs || West  `elem` legals) &&
-  not hitExplosion
-  where legals = legalMovesAt lev (fieldPos pos)
-        (sx,sy) = fieldSub pos
-        bs = 3
-
-        hitExplosion = any hitBy es
-        hitBy e = isDead e && abs (ex-px) < fieldMid && abs (ey-py) < fieldMid
-          where V ex ey = position e
-
-newDir lev rnd act = if canMove lev act && (isHalfway || rnd `mod` 1000 < 500)
-                     then Nothing
-                     else Just pickedDir
-  where legal = legalMovesAt lev (fieldPos (position act))
-        dirPool = if length legal < 2 then legal else legal \\ [turnBack (facing act)]
-        pickedDir = dirPool !! (rnd `mod` length dirPool)
-        isHalfway = halfway (fieldSub (position act)) (facing act)
-
-movePlayer level mov shoot enemies plr = case action plr of
-  Entering dir False -> let startMoving = isJust mov
-                        in plr { action = Entering dir startMoving
-                               , position = position plr + if startMoving then dirVec dir else 0
-                               }
-  Entering dir True -> if fieldSub (position plr) == (0,0)
-                       then plr { action = Walking }
-                       else plr { position = position plr + dirVec dir }
-  _ -> case mov of
-    Nothing  -> if action plr' /= Walking then animate plr' else plr'
-    Just dir -> animate (if isAlive plr then move level dir plr' else plr')
-  where plr' = case killed of
-          _ | isDead plr -> plr
-          Just enemy     -> plr { animation = deathAnimation (skin plr)
-                                , action = KilledBy (actorType enemy)
-                                , animSpeed = 6
-                                }
-          _ | shoot      -> plr { animation = shootAnimation (skin plr)
-                                , action = Shooting
-                                }
-          otherwise      -> plr
-        killed = find ((==getXY plr).getXY) [enemy | enemy <- enemies, isAlive enemy]
-        getXY = fieldPos.position
-
-moveEnemy level dir bs act = animate (mv act')
-  where act' = case hit of
-          Just (killer,_) -> act { animation = deathAnimation (skin act)
-                                 , action = KilledBy killer
-                                 }
-          Nothing -> act
-        mv = if isAlive act' then move level dir else id
-        hit = find hitBy bs
-        V px py = position act
-        hitBy (_,(V bx by)) = abs (bx-px) < fieldMid && abs (by-py) < fieldMid
-
-move :: Level -> Direction -> Actor -> Actor
-move lev dir ent = mv ent $ fmap snd . find fst $
-                   [(isHalfway dir || isAtMid && dirIsLegal, dir)
-                   ,(not isAtMid && dirIsLegal, dir')
-                   ,(isHalfway entDir || legalMove entDir, entDir)
-                   ]
-  where mv e Nothing  = e
-        mv e (Just d) = e { position = position e + fromIntegral (speed e) * dirVec d
-                          , facing = d
-                          }
-
-        dirIsLegal = legalMove dir
-        legalMove d = d `elem` legalMovesAt lev (fieldPos (position ent))
-
-        isAtMid = atFieldMid sub dir
-        isHalfway = halfway sub
-
-        sub@(sx,sy) = fieldSub (position ent)
-
-        entDir = facing ent
-        dir' = case entDir of
-          North | sy > 0 -> South
-          East  | sx > 0 -> West
-          South | sy < 0 -> North
-          West  | sx < 0 -> East
-          otherwise      -> entDir
-
-canMove :: Level -> Actor -> Bool
-canMove lev ent = halfway || facing ent `elem` legalMovesAt lev (fieldPos (position ent))
-  where (sx,sy) = fieldSub (position ent)
-        halfway = sx /= 0 || sy /= 0
-
-legalMovesAt lev pos = legalMoves lev ! ix pos
-  where ix (x,y) = (snd (levelSize lev)-1-y,x)
-
-animate :: Actor -> Actor
-animate ent = let ent' = ent { tick = (tick ent+1) `mod` animSpeed ent }
-                  adv = if tick ent' == 0 then 1 else 0
-                  animation' = drop adv (animation ent') in
-  case action ent' of
-    Entering _ _ -> ent'
-    Walking -> ent' { animation = animation' }
-    Shooting -> if null animation'
-                then ent' { animation = walkAnimation (skin ent')
-                          , action = Walking
-                          }
-                else ent' { animation = animation' }
-    KilledBy _ -> ent' { animation = animation' }
-
-dirVec North = V 0 1
-dirVec East  = V 1 0
-dirVec South = V 0 (-1)
-dirVec West  = V (-1) 0
+{-# LANGUAGE RecursiveDo #-}
+
+module Game where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Data.Array
+import Data.List
+import Data.Maybe
+import FRP.Elerea.Simple
+
+import Actor
+import GraphUtils
+import HighScore
+import Level
+import Sprites
+import Utils
+import Vector
+
+numberOfLives = 5
+
+data LevelState = LevelState
+                  { level :: Level
+                  , actors :: [Actor]
+                  , bullets :: [(ActorType,Vec)]
+                  , shooters :: [ActorType]
+                  }
+
+keySet1 = fst
+keySet2 = snd
+
+keyDir (True,_,_,_,_) = Just North
+keyDir (_,True,_,_,_) = Just South
+keyDir (_,_,True,_,_) = Just West
+keyDir (_,_,_,True,_) = Just East
+keyDir _              = Nothing
+
+keyShoot (_,_,_,_,s) = s
+
+keyAny k = keyShoot k || isJust (keyDir k)
+
+game highScore storeScore (renderGame,renderMenu) closeAction newActor levels keyPress = do
+  let firstTrue s = do
+        mask <- delay False =<< transfer False (||) s
+        return (liftA2 (&&) (not <$> mask) s)
+
+      mkGame 0 = playGame storeScore renderGame newActor levels keyPress 1
+      mkGame 1 = playGame storeScore renderGame newActor levels keyPress 2
+      mkGame _ = return (pure (void closeAction),pure True)
+
+  keys <- memo (keySet1 <$> keyPress)
+  (output,_) <- switcher . flip fmap highScore $ \score -> do
+    (menu,pick) <- displayMenu (renderMenu score) ["ONE PLAYER GAME","TWO PLAYER GAME","QUIT"] keys
+    picked <- firstTrue (keyShoot <$> keys)
+    gameSource <- generator (toMaybe <$> picked <*> (mkGame <$> pick))
+    fullOutput <- menu --> gameSource
+    return (fst =<< fullOutput,snd =<< fullOutput)
+
+  return output
+
+displayMenu renderMenu items keys = do
+  let val False = 0
+      val True  = 1
+
+  up <- edge ((==Just North) . keyDir <$> keys)
+  down <- edge ((==Just South) . keyDir <$> keys)
+  item <- transfer2 0 (\u d i -> (i + val d - val u) `mod` length items) up down
+
+  return ((renderMenu items <$> item,pure False),item)
+
+playGame storeScore renderFun newActor levels keyPress numPlayers = mdo
+  let startLevel level enemyCount = playLevel newActor keyPress level numPlayers lives' enemyCount
+      players = take numPlayers [YellowWorrior,BlueWorrior]
+
+      pickLevel cnt rnd = case () of
+        _ | cnt == 4         -> findLevel (=="arena")
+        _ | cnt < 8          -> findLevel ((=='b').head)
+        _ | cnt `mod` 6 == 1 -> findLevel (=="pit")
+        otherwise            -> findLevel ((=='w').head)
+        where findLevel p = pickOne (filter (p.levelName) levels)
+              pickOne xs = xs !! (rnd `mod` length xs)
+
+      accumScore player state prev = max 0 $ prev +
+                                     (sum . map killScore . actors) state -
+                                     10 * (length . filter (==player) . shooters) state
+        where killScore a = if justDied a && action a == KilledBy player then actorValue a else 0
+
+      accumLives player state prev = max 0 $ prev + (sum . map lifeLost . actors) state
+        where lifeLost a = if justDied a && actorType a == player then -1 else 0
+
+  levelNoise <- noise
+  (state,trigLevel) <- switcher (startLevel <$> (pickLevel <$> levelCount <*> levelNoise) <*> levelCount)
+  trigLevel' <- delay False trigLevel
+  levelCount <- transfer 1 (\win cnt -> if win then cnt+1 else cnt) trigLevel'
+  scores <- memo =<< (sequence <$> forM players (\t -> transfer 0 (accumScore t) state))
+  lives <- memo =<< (sequence <$> forM players (\t -> transfer numberOfLives (accumLives t) state))
+  lives' <- delay (replicate numPlayers numberOfLives) lives
+
+  gameOver <- memo (all (==0) <$> lives)
+
+  return (liftA2 (>>)
+          ((\c s -> when c (storeScore s)) <$> gameOver <*> scores)
+          (renderFun <$> state <*> levelCount <*> scores <*> lives)
+         ,gameOver
+         )
+
+playLevel newActor keyPress level numPlayers lives enemyCount = mdo
+  let mkEnemy etype = enemy (newActor etype) (if etype == Worluk then 2 else 1) level bullets
+
+      mkShot c plr = if c && canShoot
+                     then (:[]) <$> bullet (actorType plr) (position plr) (facing plr)
+                     else return []
+        where canShoot = case action plr of
+                Walking  -> True
+                Shooting -> True
+                _        -> False
+
+      spawnEnemies oldEnemies = concatMap (spawnEnemy (length oldEnemies == 1)) oldEnemies
+      spawnEnemy isLast enemy = if justDied enemy then
+                                    case actorType enemy of
+                                      Burwor  -> [mkEnemy Garwor <$> (position <$> head players)]
+                                      Garwor  -> [mkEnemy Thorwor <$> (position <$> head players)]
+                                      Thorwor -> if isLast then [mkEnemy Worluk <$> (position <$> head players)] else []
+                                      _       -> []
+                                else []
+
+      (lw,lh) = levelSize level
+      playerInit = take numPlayers [(YellowWorrior,keySet1,1),(BlueWorrior,keySet2,0)]
+
+  (players,bulletSources) <- fmap unzip $ forM (zip playerInit [0..]) $ \((worType,keySet,pix),lix) -> do
+    shoot <- edge (keyShoot . keySet <$> keyPress)
+
+    (player,_respawn) <- switcher . flip fmap lives $ \ls -> do
+      let (pedir,py,px) = entrances level !! pix
+          playerInit = (newActor worType (V (px*fieldSize) ((lh-py-1)*fieldSize)))
+                         { action = Entering pedir False
+                         , facing = [East,West] !! pix
+                         }
+          respawn plr = ls !! lix > 1 && null (animation plr)
+
+      if ls !! lix == 0
+        then return (pure (playerInit { animation = [] }),pure False)
+        else do plr <- transfer3 playerInit (movePlayer level) (keyDir . keySet <$> keyPress) shoot enemies'
+                return (plr, respawn <$> plr)
+
+    bulletSource <- generator (mkShot <$> shoot <*> player)
+    return (player,bulletSource)
+
+  newBullets <- memo (concat <$> sequence bulletSources)
+  bullets <- collection newBullets (notHitAnything level <$> enemies')
+  let shooters = fmap (map fst) . sequence =<< newBullets
+
+  initialEnemies <- replicateM enemyCount (mkEnemy Burwor (V (-3*fieldSize) (-3*fieldSize)))
+  spawnedEnemies <- generator (sequence <$> (sequence . spawnEnemies =<< enemies'))
+  enemySource <- delay initialEnemies spawnedEnemies
+  enemies <- collection enemySource (pure (not . null . animation))
+  enemies' <- delay [] enemies
+
+  return (LevelState level <$> (liftA2 (++) (sequence players) enemies) <*> bullets <*> shooters
+         ,null <$> enemies
+         )
+
+bullet src pos dir = fmap ((,) src) <$> stateful pos (+3*dirVec dir)
+
+enemy newActor moveSpeed level bullets (V playerX playerY) = mdo
+  let actorInit = (newActor (fromIntegral fieldSize*startPos)) { speed = moveSpeed, animSpeed = 4 }
+      startPos = if abs (startX-playerX `div` fieldSize) < 3 && abs (startY-playerY `div` fieldSize) < 3
+                 then V ((startX + lw `div` 2) `mod` lw) ((startY + lh `div` 2) `mod` lh)
+                 else V startX startY
+      (lw,lh) = levelSize level
+
+  startX <- (`mod` lw) <$> getRandom
+  startY <- (`mod` lh) <$> getRandom
+  startDir <- toEnum . (`mod` 4) <$> getRandom
+  dirNoise <- noise
+
+  actorInput <- startDir --> newDir level <$> dirNoise <*> actor'
+  actor <- transfer2 actorInit (moveEnemy level) actorInput bullets
+  actor' <- delay actorInit actor
+  return actor
+
+notHitAnything lev es (_,pos@(V px py)) =
+  (sy <  fieldMid-bs || North `elem` legals) &&
+  (sx <  fieldMid-bs || East  `elem` legals) &&
+  (sy > -fieldMid+bs || South `elem` legals) &&
+  (sx > -fieldMid+bs || West  `elem` legals) &&
+  not hitExplosion
+  where legals = legalMovesAt lev (fieldPos pos)
+        (sx,sy) = fieldSub pos
+        bs = 3
+
+        hitExplosion = any hitBy es
+        hitBy e = isDead e && abs (ex-px) < fieldMid && abs (ey-py) < fieldMid
+          where V ex ey = position e
+
+newDir lev rnd act = if canMove lev act && (isHalfway || rnd `mod` 1000 < 500)
+                     then Nothing
+                     else Just pickedDir
+  where legal = legalMovesAt lev (fieldPos (position act))
+        dirPool = if length legal < 2 then legal else legal \\ [turnBack (facing act)]
+        pickedDir = dirPool !! (rnd `mod` length dirPool)
+        isHalfway = halfway (fieldSub (position act)) (facing act)
+
+movePlayer level mov shoot enemies plr = case action plr of
+  Entering dir False -> let startMoving = isJust mov
+                        in plr { action = Entering dir startMoving
+                               , position = position plr + if startMoving then dirVec dir else 0
+                               }
+  Entering dir True -> if fieldSub (position plr) == (0,0)
+                       then plr { action = Walking }
+                       else plr { position = position plr + dirVec dir }
+  _ -> case mov of
+    Nothing  -> if action plr' /= Walking then animate plr' else plr'
+    Just dir -> animate (if isAlive plr then move level dir plr' else plr')
+  where plr' = case killed of
+          _ | isDead plr -> plr
+          Just enemy     -> plr { animation = deathAnimation (skin plr)
+                                , action = KilledBy (actorType enemy)
+                                , animSpeed = 6
+                                }
+          _ | shoot      -> plr { animation = shootAnimation (skin plr)
+                                , action = Shooting
+                                }
+          otherwise      -> plr
+        killed = find ((==getXY plr).getXY) [enemy | enemy <- enemies, isAlive enemy]
+        getXY = fieldPos.position
+
+moveEnemy level dir bs act = animate (mv act')
+  where act' = case hit of
+          Just (killer,_) -> act { animation = deathAnimation (skin act)
+                                 , action = KilledBy killer
+                                 }
+          Nothing -> act
+        mv = if isAlive act' then move level dir else id
+        hit = find hitBy bs
+        V px py = position act
+        hitBy (_,(V bx by)) = abs (bx-px) < fieldMid && abs (by-py) < fieldMid
+
+move :: Level -> Direction -> Actor -> Actor
+move lev dir ent = mv ent $ fmap snd . find fst $
+                   [(isHalfway dir || isAtMid && dirIsLegal, dir)
+                   ,(not isAtMid && dirIsLegal, dir')
+                   ,(isHalfway entDir || legalMove entDir, entDir)
+                   ]
+  where mv e Nothing  = e
+        mv e (Just d) = e { position = position e + fromIntegral (speed e) * dirVec d
+                          , facing = d
+                          }
+
+        dirIsLegal = legalMove dir
+        legalMove d = d `elem` legalMovesAt lev (fieldPos (position ent))
+
+        isAtMid = atFieldMid sub dir
+        isHalfway = halfway sub
+
+        sub@(sx,sy) = fieldSub (position ent)
+
+        entDir = facing ent
+        dir' = case entDir of
+          North | sy > 0 -> South
+          East  | sx > 0 -> West
+          South | sy < 0 -> North
+          West  | sx < 0 -> East
+          otherwise      -> entDir
+
+canMove :: Level -> Actor -> Bool
+canMove lev ent = halfway || facing ent `elem` legalMovesAt lev (fieldPos (position ent))
+  where (sx,sy) = fieldSub (position ent)
+        halfway = sx /= 0 || sy /= 0
+
+legalMovesAt lev pos = legalMoves lev ! ix pos
+  where ix (x,y) = (snd (levelSize lev)-1-y,x)
+
+animate :: Actor -> Actor
+animate ent = let ent' = ent { tick = (tick ent+1) `mod` animSpeed ent }
+                  adv = if tick ent' == 0 then 1 else 0
+                  animation' = drop adv (animation ent') in
+  case action ent' of
+    Entering _ _ -> ent'
+    Walking -> ent' { animation = animation' }
+    Shooting -> if null animation'
+                then ent' { animation = walkAnimation (skin ent')
+                          , action = Walking
+                          }
+                else ent' { animation = animation' }
+    KilledBy _ -> ent' { animation = animation' }
+
+dirVec North = V 0 1
+dirVec East  = V 1 0
+dirVec South = V 0 (-1)
+dirVec West  = V (-1) 0
diff --git a/src/GraphUtils.hs b/src/GraphUtils.hs
--- a/src/GraphUtils.hs
+++ b/src/GraphUtils.hs
@@ -1,31 +1,31 @@
-module GraphUtils where
-
-import Data.Word
-import Foreign.Marshal
-import Foreign.Ptr
-import Graphics.Rendering.OpenGL
-
-createTexture :: Int -> Int -> Bool -> (Ptr Word8 -> IO ()) -> IO TextureObject
-createTexture width height looped fill = allocaArray (width*height*4) $ \tex -> do
-  fill tex
-  [tid] <- genObjectNames 1
-  textureBinding Texture2D $= Just tid
-  if looped
-    then do textureWrapMode Texture2D S $= (Repeated,Repeat)
-            textureWrapMode Texture2D T $= (Repeated,Repeat)
-    else do textureWrapMode Texture2D S $= (Mirrored,Clamp)
-            textureWrapMode Texture2D T $= (Mirrored,Clamp)
-  build2DMipmaps Texture2D RGBA' (fromIntegral width) (fromIntegral height) (PixelData RGBA UnsignedByte tex)
-  return tid
-
-vertex3 :: GLfloat -> GLfloat -> GLfloat -> IO ()
-vertex3 x y z = vertex $ Vertex3 x y z
-
-texCoord2 :: GLfloat -> GLfloat -> IO ()
-texCoord2 x y = texCoord $ TexCoord2 x y
-
-explodeList :: Int -> [a] -> [a]
-explodeList = concatMap . replicate
-
-explodeMatrix :: Int -> [[a]] -> [[a]]
-explodeMatrix n = map (explodeList n) . explodeList n
+module GraphUtils where
+
+import Data.Word
+import Foreign.Marshal
+import Foreign.Ptr
+import Graphics.Rendering.OpenGL
+
+createTexture :: Int -> Int -> Bool -> (Ptr Word8 -> IO ()) -> IO TextureObject
+createTexture width height looped fill = allocaArray (width*height*4) $ \tex -> do
+  fill tex
+  [tid] <- genObjectNames 1
+  textureBinding Texture2D $= Just tid
+  if looped
+    then do textureWrapMode Texture2D S $= (Repeated,Repeat)
+            textureWrapMode Texture2D T $= (Repeated,Repeat)
+    else do textureWrapMode Texture2D S $= (Mirrored,Clamp)
+            textureWrapMode Texture2D T $= (Mirrored,Clamp)
+  build2DMipmaps Texture2D RGBA' (fromIntegral width) (fromIntegral height) (PixelData RGBA UnsignedByte tex)
+  return tid
+
+vertex3 :: GLfloat -> GLfloat -> GLfloat -> IO ()
+vertex3 x y z = vertex $ Vertex3 x y z
+
+texCoord2 :: GLfloat -> GLfloat -> IO ()
+texCoord2 x y = texCoord $ TexCoord2 x y
+
+explodeList :: Int -> [a] -> [a]
+explodeList = concatMap . replicate
+
+explodeMatrix :: Int -> [[a]] -> [[a]]
+explodeMatrix n = map (explodeList n) . explodeList n
diff --git a/src/HighScore.hs b/src/HighScore.hs
--- a/src/HighScore.hs
+++ b/src/HighScore.hs
@@ -1,36 +1,36 @@
-module HighScore where
-
-import Control.Monad
-import System.Directory
-import System.IO
-
-loadScore :: IO Int
-loadScore = do
-  dir <- getAppDir
-
-  let fileName = dir ++ "/highscore"
-  fileChk <- doesFileExist fileName
-  unless fileChk $ do
-    hdl <- openFile fileName WriteMode
-    hPutStr hdl "0"
-    hClose hdl
-
-  hdl <- openFile fileName ReadMode
-  score <- hGetLine hdl
-  hClose hdl
-
-  return (read score)
-
-saveScore :: Int -> IO ()
-saveScore score = do
-  dir <- getAppDir
-  hdl <- openFile (dir ++ "/highscore") WriteMode
-  hPutStr hdl (show score)
-  hClose hdl
-
-getAppDir :: IO FilePath
-getAppDir = do
-  dir <- getAppUserDataDirectory "dow"
-  dirChk <- doesDirectoryExist dir
-  unless dirChk $ createDirectory dir
+module HighScore where
+
+import Control.Monad
+import System.Directory
+import System.IO
+
+loadScore :: IO Int
+loadScore = do
+  dir <- getAppDir
+
+  let fileName = dir ++ "/highscore"
+  fileChk <- doesFileExist fileName
+  unless fileChk $ do
+    hdl <- openFile fileName WriteMode
+    hPutStr hdl "0"
+    hClose hdl
+
+  hdl <- openFile fileName ReadMode
+  score <- hGetLine hdl
+  hClose hdl
+
+  return (read score)
+
+saveScore :: Int -> IO ()
+saveScore score = do
+  dir <- getAppDir
+  hdl <- openFile (dir ++ "/highscore") WriteMode
+  hPutStr hdl (show score)
+  hClose hdl
+
+getAppDir :: IO FilePath
+getAppDir = do
+  dir <- getAppUserDataDirectory "dow"
+  dirChk <- doesDirectoryExist dir
+  unless dirChk $ createDirectory dir
   return dir
diff --git a/src/Level.hs b/src/Level.hs
--- a/src/Level.hs
+++ b/src/Level.hs
@@ -1,93 +1,93 @@
-module Level where
-
-import Control.Monad
-import Data.Array
-import Data.List
-
-import Vector
-
-data Level = Level
-             { levelName :: String
-             , levelSize :: (Int,Int)
-             , legalMoves :: Array (Int,Int) [Direction]
-             , doors :: [(Direction,Int)]
-             , entrances :: [(Direction,Int,Int)]
-             } deriving Show
-
-data Direction = North | East | South | West
-               deriving (Eq, Enum, Show)
-
-fieldSize :: Int
-fieldSize = 16
-
-fieldMid :: Int
-fieldMid = fieldSize `div` 2
-
-fieldPos :: Vec -> (Int,Int)
-fieldPos (V x y) = ((x+fieldMid) `div` fieldSize, (y+fieldMid) `div` fieldSize)
-
-fieldSub :: Vec -> (Int,Int)
-fieldSub (V x y) = (mkSub x, mkSub y)
-  where mkSub c = let s = c `mod` fieldSize in if s >= fieldMid then s-fieldSize else s
-
-atFieldMid :: (Int,Int) -> Direction -> Bool
-atFieldMid (sx,sy) dir = 0 == if isVertical dir then sx else sy
-
-halfway :: (Int,Int) -> Direction -> Bool
-halfway (sx,sy) dir = 0 /= if isVertical dir then sy else sx
-
-dirFromInt :: Int -> Direction
-dirFromInt = toEnum . (`mod` 4)
-
-turnRight :: Direction -> Direction
-turnRight = dirFromInt . (+1) . fromEnum
-
-turnBack :: Direction -> Direction
-turnBack = dirFromInt . (+2) . fromEnum
-
-turnLeft :: Direction -> Direction
-turnLeft = dirFromInt . (+3) . fromEnum
-
-isVertical :: Direction -> Bool
-isVertical North = True
-isVertical South = True
-isVertical _     = False
-
-parseLevel :: [String] -> Maybe (Level,[String])
-parseLevel lines = do
-  let lines' = dropWhile null lines
-      nameLine = head lines'
-      (mazeLines,rest) = span (not . null) (tail lines')
-      width = length (head mazeLines) `div` 2
-      height = length mazeLines `div` 2
-
-      mkEntrance (North,x) = (South,-1,x)
-      mkEntrance (South,x) = (North,height,x)
-      mkEntrance (East,y) = (West,y,width)
-      mkEntrance (West,y) = (East,y,-1)
-
-      makeMoves lines = concat . odds $ zipWith3 f lines (tail lines) (tail (tail lines))
-        where f n c s = odds $ zipWith4 f' (tail n) (tail s) c (tail (tail c))
-              f' n s w e = (if n == ' ' then [North] else []) ++
-                           (if s == ' ' then [South] else []) ++
-                           (if w == ' ' then [West] else []) ++
-                           (if e == ' ' then [East] else [])
-
-      odds (x:_:xs) = x : odds xs
-      odds xs = xs
-
-      chars `onEdgeOf` lines =
-        [(d,i `div` 2) |
-         (d,f) <- [(North,head),(South,last),(West,map head),(East,map last)],
-         i <- findIndices (`elem` chars) (f lines)]
-
-  guard $ not (null lines')
-  guard $ length mazeLines > 2
-  guard $ head nameLine == '"'
-
-  return (Level { levelName = takeWhile (/= '"') (tail nameLine)
-                , levelSize = (width,height)
-                , legalMoves = listArray ((0,0),(height-1,width-1)) (makeMoves mazeLines)
-                , doors = "<>^v" `onEdgeOf` mazeLines
-                , entrances = map mkEntrance ("*" `onEdgeOf` mazeLines)
-                }, rest)
+module Level where
+
+import Control.Monad
+import Data.Array
+import Data.List
+
+import Vector
+
+data Level = Level
+             { levelName :: String
+             , levelSize :: (Int,Int)
+             , legalMoves :: Array (Int,Int) [Direction]
+             , doors :: [(Direction,Int)]
+             , entrances :: [(Direction,Int,Int)]
+             } deriving Show
+
+data Direction = North | East | South | West
+               deriving (Eq, Enum, Show)
+
+fieldSize :: Int
+fieldSize = 16
+
+fieldMid :: Int
+fieldMid = fieldSize `div` 2
+
+fieldPos :: Vec -> (Int,Int)
+fieldPos (V x y) = ((x+fieldMid) `div` fieldSize, (y+fieldMid) `div` fieldSize)
+
+fieldSub :: Vec -> (Int,Int)
+fieldSub (V x y) = (mkSub x, mkSub y)
+  where mkSub c = let s = c `mod` fieldSize in if s >= fieldMid then s-fieldSize else s
+
+atFieldMid :: (Int,Int) -> Direction -> Bool
+atFieldMid (sx,sy) dir = 0 == if isVertical dir then sx else sy
+
+halfway :: (Int,Int) -> Direction -> Bool
+halfway (sx,sy) dir = 0 /= if isVertical dir then sy else sx
+
+dirFromInt :: Int -> Direction
+dirFromInt = toEnum . (`mod` 4)
+
+turnRight :: Direction -> Direction
+turnRight = dirFromInt . (+1) . fromEnum
+
+turnBack :: Direction -> Direction
+turnBack = dirFromInt . (+2) . fromEnum
+
+turnLeft :: Direction -> Direction
+turnLeft = dirFromInt . (+3) . fromEnum
+
+isVertical :: Direction -> Bool
+isVertical North = True
+isVertical South = True
+isVertical _     = False
+
+parseLevel :: [String] -> Maybe (Level,[String])
+parseLevel lines = do
+  let lines' = dropWhile null lines
+      nameLine = head lines'
+      (mazeLines,rest) = span (not . null) (tail lines')
+      width = length (head mazeLines) `div` 2
+      height = length mazeLines `div` 2
+
+      mkEntrance (North,x) = (South,-1,x)
+      mkEntrance (South,x) = (North,height,x)
+      mkEntrance (East,y) = (West,y,width)
+      mkEntrance (West,y) = (East,y,-1)
+
+      makeMoves lines = concat . odds $ zipWith3 f lines (tail lines) (tail (tail lines))
+        where f n c s = odds $ zipWith4 f' (tail n) (tail s) c (tail (tail c))
+              f' n s w e = (if n == ' ' then [North] else []) ++
+                           (if s == ' ' then [South] else []) ++
+                           (if w == ' ' then [West] else []) ++
+                           (if e == ' ' then [East] else [])
+
+      odds (x:_:xs) = x : odds xs
+      odds xs = xs
+
+      chars `onEdgeOf` lines =
+        [(d,i `div` 2) |
+         (d,f) <- [(North,head),(South,last),(West,map head),(East,map last)],
+         i <- findIndices (`elem` chars) (f lines)]
+
+  guard $ not (null lines')
+  guard $ length mazeLines > 2
+  guard $ head nameLine == '"'
+
+  return (Level { levelName = takeWhile (/= '"') (tail nameLine)
+                , levelSize = (width,height)
+                , legalMoves = listArray ((0,0),(height-1,width-1)) (makeMoves mazeLines)
+                , doors = "<>^v" `onEdgeOf` mazeLines
+                , entrances = map mkEntrance ("*" `onEdgeOf` mazeLines)
+                }, rest)
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,89 +1,92 @@
-module Main where
-
-import Control.Applicative
-import Control.Monad
-import Control.Monad.Fix
-import Data.IORef
-import Data.List
-import FRP.Elerea.Simple
-import Graphics.UI.GLFW
-import Graphics.Rendering.OpenGL
-
-import Actor
-import Game
-import HighScore
-import Level
-import Render
-import Sprites
-import Text
-
-import Paths_dow (getDataFileName)
-
-main = do
-  initialize
-  openWindow (Size 640 480) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window
-  windowTitle $= "Dungeons of Wor"
-
-  aspectRatio <- newIORef 1
-  levels <- loadLevels =<< getDataFileName "data/levels.txt"
-  sprites <- loadSprites =<< getDataFileName "data/sprites.txt"
-  charset <- loadCharset =<< getDataFileName "data/charset.txt"
-  render <- getRenderFunctions aspectRatio charset
-
-  let skins = createSkins sprites
-      newActor = mkActor skins
-
-  windowSizeCallback $= setViewport aspectRatio
-
-  closed <- newIORef False
-  let closeAction = writeIORef closed True >> return True
-  windowCloseCallback $= closeAction
-
-  clearColor $= Color4 0 0 0 1
-  blend $= Enabled
-  blendFunc $= (SrcAlpha,OneMinusSrcAlpha)
-  textureFilter Texture2D $= ((Linear',Just Nearest),Linear')
-  textureFunction $= Combine4
-
-  let noKeys = (False,False,False,False,False)
-  (keyPress,keySink) <- external (noKeys,noKeys)
-  (highScore,highScoreSink) <- external =<< loadScore
-  let storeScore scores = do
-        oldScore <- loadScore
-        let newScore = maximum (oldScore:scores)
-        saveScore newScore
-        highScoreSink newScore
-
-  renderAction <- start $ game highScore storeScore render closeAction newActor levels keyPress
-
-  fix $ \loop -> do
-    readKeys keySink
-    join renderAction
-    sleep 0.02
-    stop <- readIORef closed
-    esc <- getKey ESC
-    when (not stop && esc /= Press) loop
-
-  closeWindow
-
-loadLevels file = unfoldr parseLevel . lines <$> readFile file
-
-loadSprites file = do
-  dat <- lines <$> readFile file
-  parseSprites dat
-
-readKeys sink = do
-  let pr = (==Press)
-  kn1 <- getKey UP
-  ks1 <- getKey DOWN
-  kw1 <- getKey LEFT
-  ke1 <- getKey RIGHT
-  kt1a <- getKey RCTRL
-  kt1b <- getKey ENTER
-  kn2 <- getKey 'W'
-  ks2 <- getKey 'S'
-  kw2 <- getKey 'A'
-  ke2 <- getKey 'D'
-  kt2 <- getKey LCTRL
-  sink ((pr kn1, pr ks1, pr kw1, pr ke1, pr kt1a || pr kt1b),
-        (pr kn2, pr ks2, pr kw2, pr ke2, pr kt2))
+module Main where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Data.IORef
+import Data.List
+import FRP.Elerea.Simple
+import Graphics.UI.GLFW
+import Graphics.Rendering.OpenGL
+
+import Actor
+import Game
+import HighScore
+import Level
+import Render
+import Sprites
+import Text
+
+import Paths_dow (getDataFileName)
+
+main = do
+  initialize
+  openWindow (Size 640 480) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window
+  windowTitle $= "Dungeons of Wor"
+
+  aspectRatio <- newIORef 1
+  levels <- loadLevels =<< getDataFileName "data/levels.txt"
+  sprites <- loadSprites =<< getDataFileName "data/sprites.txt"
+  charset <- loadCharset =<< getDataFileName "data/charset.txt"
+  render <- getRenderFunctions aspectRatio charset
+
+  let skins = createSkins sprites
+      newActor = mkActor skins
+
+  windowSizeCallback $= setViewport aspectRatio
+
+  closed <- newIORef False
+  let closeAction = writeIORef closed True >> return True
+  windowCloseCallback $= closeAction
+
+  clearColor $= Color4 0 0 0 1
+  blend $= Enabled
+  blendFunc $= (SrcAlpha,OneMinusSrcAlpha)
+  textureFilter Texture2D $= ((Linear',Just Nearest),Linear')
+  textureFunction $= Combine4
+
+  let noKeys = (False,False,False,False,False)
+  (keyPressGen,keySink) <- external (noKeys,noKeys)
+  (highScoreGen,highScoreSink) <- external =<< loadScore
+  let storeScore scores = do
+        oldScore <- loadScore
+        let newScore = maximum (oldScore:scores)
+        saveScore newScore
+        highScoreSink newScore
+
+  renderAction <- start $ do
+    keyPress <- keyPressGen
+    highScore <- highScoreGen
+    game highScore storeScore render closeAction newActor levels keyPress
+
+  fix $ \loop -> do
+    readKeys keySink
+    join renderAction
+    sleep 0.02
+    stop <- readIORef closed
+    esc <- getKey ESC
+    when (not stop && esc /= Press) loop
+
+  closeWindow
+
+loadLevels file = unfoldr parseLevel . lines <$> readFile file
+
+loadSprites file = do
+  dat <- lines <$> readFile file
+  parseSprites dat
+
+readKeys sink = do
+  let pr = (==Press)
+  kn1 <- getKey UP
+  ks1 <- getKey DOWN
+  kw1 <- getKey LEFT
+  ke1 <- getKey RIGHT
+  kt1a <- getKey RCTRL
+  kt1b <- getKey ENTER
+  kn2 <- getKey 'W'
+  ks2 <- getKey 'S'
+  kw2 <- getKey 'A'
+  ke2 <- getKey 'D'
+  kt2 <- getKey LCTRL
+  sink ((pr kn1, pr ks1, pr kw1, pr ke1, pr kt1a || pr kt1b),
+        (pr kn2, pr ks2, pr kw2, pr ke2, pr kt2))
diff --git a/src/Render.hs b/src/Render.hs
--- a/src/Render.hs
+++ b/src/Render.hs
@@ -1,251 +1,251 @@
-module Render
-       ( getAspectRatio
-       , getRenderFunctions
-       , setViewport
-       ) where
-
-import Control.Monad
-import Data.Array
-import Data.Char
-import Data.IORef
-import Foreign.Marshal
-import Graphics.UI.GLFW
-import Graphics.Rendering.OpenGL hiding (position)
-
-import Actor as A
-import Game
-import GraphUtils
-import Level
-import Text
-import Vector
-
-hudHeight = 0.2
-
-solid :: GLfloat
-solid = 1
-
-fullLevelSize = addBorder . levelSize
-  where addBorder (w,h) = (w+2,h+2)
-
-getAspectRatio level = fromIntegral lh / fromIntegral lw + hudHeight
-  where (lw,lh) = fullLevelSize level
-
-setViewport ref size@(Size w h) = do
-  lr <- readIORef ref
-
-  let r = (fromIntegral h/fromIntegral w)
-      r' = recip r
-      lr' = recip lr
-      s = 2*min (max 1 (min lr' r')) (max (r/lr) lr')
-
-  viewport $= (Position 0 0,size)
-
-  matrixMode $= Projection
-  loadIdentity
-  scale (s*min 1 r) (s*min 1 r') (1 :: GLfloat)
-  translate $ Vector3 (-0.5) (-0.5*lr) (0 :: GLfloat)
-
-  matrixMode $= Modelview 0
-
-setAspectRatio ref val = do
-  writeIORef ref val
-  setViewport ref =<< get windowSize
-
-getRenderFunctions aspectRatio charset = do
-  let displayText = uncurry displayString charset
-
-  rgbOverlay <- createTexture 24 24 True $ flip pokeArray $
-                concat [if b then [95,95,95,255] else c | y <- [0..23], x <- [0..23],
-                        let c = case x `div` 4 `mod` 3 of
-                              0 -> [255,191,191,255]
-                              1 -> [191,255,191,255]
-                              2 -> [191,191,255,255]
-                            b = x `mod` 4 == 0 || x < 12 && y `mod` 12 == 0 || x >= 12 && y `mod` 12 == 6
-                       ]
-
-  return (renderGame aspectRatio displayText rgbOverlay
-         ,renderMenu aspectRatio displayText rgbOverlay
-         )
-
-renderMenu aspectRatio displayText rgbOverlay score items item = do
-  let charSize = 0.006
-      textCol = Color4 1 0 0 solid
-      activeCol = Color4 0.93 0.79 0 solid
-      menu = "DUNGEONS OF WOR":"":"":items++["","","HIGH SCORE "++show score]
-
-  setAspectRatio aspectRatio 1
-
-  clear [ColorBuffer]
-  loadIdentity
-
-  texture Texture2D $= Enabled
-  forM_ (zip menu [-3..]) $ \(text,i) -> do
-    color $ if i == item then activeCol else textCol
-    displayText (0.5-(fromIntegral (length text)*4*charSize))
-                (0.5+charSize*(7*fromIntegral (length items-1-2*i)))
-                charSize text
-
-  renderOverlay rgbOverlay
-
-  flush
-  swapBuffers
-
-renderGame aspectRatio displayText rgbOverlay levelState levelCount scores lives = do
-  let curLevel = level levelState
-      (lw,lh) = fullLevelSize curLevel
-      height = fromIntegral lh / fromIntegral lw
-      magn = 1 / fromIntegral lw
-
-  setAspectRatio aspectRatio (getAspectRatio curLevel)
-
-  clear [ColorBuffer]
-  loadIdentity
-
-  renderHud displayText height scores lives (actors levelState) levelCount curLevel
-  preservingMatrix $ do
-    translate $ Vector3 0 hudHeight (0 :: GLfloat)
-    scale magn magn (1 :: GLfloat)
-
-    renderLevel curLevel
-    renderBullets (bullets levelState)
-    renderActors (actors levelState)
-
-  renderOverlay rgbOverlay
-
-  flush
-  swapBuffers
-
-renderOverlay rgbOverlay = do
-  texture Texture2D $= Enabled
-  textureBinding Texture2D $= Just rgbOverlay
-  blendFunc $= (Zero,SrcColor)
-  color $ Color4 1 1 1 solid
-  let pscale = 100
-  renderPrimitive Quads $ do
-    texCoord2 0 0
-    vertex3 0 0 0
-    texCoord2 pscale 0
-    vertex3 1 0 0
-    texCoord2 pscale pscale
-    vertex3 1 1 0
-    texCoord2 0 pscale
-    vertex3 0 1 0
-  blendFunc $= (SrcAlpha,OneMinusSrcAlpha)
-
-renderLevel level = do
-  let (lw,lh) = fullLevelSize level
-      height = fromIntegral lh / fromIntegral lw
-      entries = [((y,x),[]) | (_,y,x) <- entrances level]
-
-  texture Texture2D $= Disabled
-  color $ Color4 0.2 0.5 1 solid
-  forM_ (entries ++ assocs (legalMoves level)) $ \((y,x),ms) -> do
-    let xc = fromIntegral (x+1)
-        yc = fromIntegral (lh-y-2)
-    unless (North `elem` ms) $ drawRectangle xc (yc+0.95) 1 0.05
-    unless (South `elem` ms) $ drawRectangle xc yc 1 0.05
-    unless (East `elem` ms) $ drawRectangle (xc+0.95) yc 0.05 1
-    unless (West `elem` ms) $ drawRectangle xc yc 0.05 1
-
-renderActors as = do
-  let players = filter ((`elem` [BlueWorrior,YellowWorrior]) . actorType) as
-  texture Texture2D $= Enabled
-  color $ Color4 1 1 1 solid
-  forM_ as $ \a -> do
-    let V x y = A.position a
-        x' = fromIntegral x / fromIntegral fieldSize
-        y' = fromIntegral y / fromIntegral fieldSize
-        dist = case actorType a of
-          Garwor  -> 2*fieldSize
-          Thorwor -> fieldSize
-          _       -> maxBound
-        visible = any ((\(V px py) -> abs (x-px) < dist || abs (y-py) < dist) . A.position) players
-
-    when (visible && (not . null . animation) a) $
-      drawSprite (head (animation a)) (1.1+x') (1.1+y') 0.8 0.8 (facing a)
-
-renderBullets bs = do
-  texture Texture2D $= Disabled
-  color $ Color4 1 0.3 0.1 solid
-  forM_ bs $ \(_,V x y) -> do
-    let x' = fromIntegral x / fromIntegral fieldSize
-        y' = fromIntegral y / fromIntegral fieldSize
-    drawRectangle (1.45+x') (1.45+y') 0.1 0.1
-
-renderHud displayText height scores lives actors levelCount level = do
-  let r = Color4 1 0 0 solid
-      b = Color4 0.25 0.63 1 solid
-      y = Color4 0.93 0.79 0 solid
-      d = Color4 0 0 0 solid
-      charSize = 0.0028
-      radarTitle = if levelCount == 1 then "RADAR" else
-                     case levelName level of
-                       "pit"   -> "THE PIT"
-                       "arena" -> "THE ARENA"
-                       _       -> "DUNGEON " ++ show levelCount
-      (levelW,levelH) = levelSize level
-      scoreB = hudHeight / 4
-      scoreW = 0.3
-      scoreH = scoreB*3
-      radarB = charSize
-      radarW = radarF*fromIntegral levelW
-      radarH = hudHeight-radarB*4-charSize*10
-      radarF = radarH/fromIntegral levelH
-      snum1 = show (scores !! 0)
-      snum2 = show (scores !! 1)
-      lnum1 = show (lives !! 0)
-      lnum2 = show (lives !! 1)
-      numPlayers = length lives
-
-  texture Texture2D $= Disabled
-  color b
-  drawRectangle 0 0 scoreW scoreH
-  drawRectangle (0.5-radarW/2-radarB) 0 (radarW+radarB*2) (radarH+radarB*2)
-  color y
-  drawRectangle (1-scoreW) 0 scoreW scoreH
-  color d
-  drawRectangle scoreB scoreB (scoreW-2*scoreB) (scoreH-2*scoreB)
-  drawRectangle (1-scoreW+scoreB) scoreB (scoreW-2*scoreB) (scoreH-2*scoreB)
-  drawRectangle (0.5-radarW/2) radarB radarW radarH
-  forM_ actors $ \actor -> do
-    let (fx,fy) = fieldPos (position actor)
-        rx = 0.5-radarW/2+radarF*fromIntegral fx
-        ry = radarB+radarF*fromIntegral fy
-    case actorType actor of
-      Burwor -> color b >> drawRectangle rx ry radarF radarF
-      Garwor -> color y >> drawRectangle rx ry radarF radarF
-      Thorwor -> color r >> drawRectangle rx ry radarF radarF
-      _ -> return ()
-
-  texture Texture2D $= Enabled
-  color y
-  displayText (1-scoreB-(fromIntegral (length snum1)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize snum1
-  displayText (1-scoreW-3*radarB-(fromIntegral (length lnum1)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize lnum1
-  when (numPlayers > 1) $ do
-    color b
-    displayText (scoreW-scoreB-(fromIntegral (length snum2)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize snum2
-    displayText (scoreW+3*radarB) (scoreB+scoreH/2-scoreB-5*charSize) charSize lnum2
-  color r
-  displayText (0.5-(fromIntegral (length radarTitle)*4*charSize)) (radarH+radarB*3) charSize radarTitle
-
-drawRectangle :: GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
-drawRectangle x y sx sy = renderPrimitive Quads $ mapM_ vertex
-  [Vertex3 x y 0, Vertex3 (x+sx) y 0, Vertex3 (x+sx) (y+sy) 0, Vertex3 x (y+sy) 0]
-
-drawSprite :: TextureObject -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> Direction -> IO ()
-drawSprite tid x y sx sy dir = do
-  let (u1,v1,u2,v2,u3,v3,u4,v4) = case dir of
-        North -> (1,1,1,0,0,0,0,1)
-        East  -> (1,1,0,1,0,0,1,0)
-        South -> (0,1,0,0,1,0,1,1)
-        West  -> (0,1,1,1,1,0,0,0)
-  textureBinding Texture2D $= Just tid
-  renderPrimitive Quads $ do
-    texCoord2 u1 v1
-    vertex3 x y 0
-    texCoord2 u2 v2
-    vertex3 (x+sx) y 0
-    texCoord2 u3 v3
-    vertex3 (x+sx) (y+sy) 0
-    texCoord2 u4 v4
-    vertex3 x (y+sy) 0
+module Render
+       ( getAspectRatio
+       , getRenderFunctions
+       , setViewport
+       ) where
+
+import Control.Monad
+import Data.Array
+import Data.Char
+import Data.IORef
+import Foreign.Marshal
+import Graphics.UI.GLFW
+import Graphics.Rendering.OpenGL hiding (position)
+
+import Actor as A
+import Game
+import GraphUtils
+import Level
+import Text
+import Vector
+
+hudHeight = 0.2
+
+solid :: GLfloat
+solid = 1
+
+fullLevelSize = addBorder . levelSize
+  where addBorder (w,h) = (w+2,h+2)
+
+getAspectRatio level = fromIntegral lh / fromIntegral lw + hudHeight
+  where (lw,lh) = fullLevelSize level
+
+setViewport ref size@(Size w h) = do
+  lr <- readIORef ref
+
+  let r = (fromIntegral h/fromIntegral w)
+      r' = recip r
+      lr' = recip lr
+      s = 2*min (max 1 (min lr' r')) (max (r/lr) lr')
+
+  viewport $= (Position 0 0,size)
+
+  matrixMode $= Projection
+  loadIdentity
+  scale (s*min 1 r) (s*min 1 r') (1 :: GLfloat)
+  translate $ Vector3 (-0.5) (-0.5*lr) (0 :: GLfloat)
+
+  matrixMode $= Modelview 0
+
+setAspectRatio ref val = do
+  writeIORef ref val
+  setViewport ref =<< get windowSize
+
+getRenderFunctions aspectRatio charset = do
+  let displayText = uncurry displayString charset
+
+  rgbOverlay <- createTexture 24 24 True $ flip pokeArray $
+                concat [if b then [95,95,95,255] else c | y <- [0..23], x <- [0..23],
+                        let c = case x `div` 4 `mod` 3 of
+                              0 -> [255,191,191,255]
+                              1 -> [191,255,191,255]
+                              2 -> [191,191,255,255]
+                            b = x `mod` 4 == 0 || x < 12 && y `mod` 12 == 0 || x >= 12 && y `mod` 12 == 6
+                       ]
+
+  return (renderGame aspectRatio displayText rgbOverlay
+         ,renderMenu aspectRatio displayText rgbOverlay
+         )
+
+renderMenu aspectRatio displayText rgbOverlay score items item = do
+  let charSize = 0.006
+      textCol = Color4 1 0 0 solid
+      activeCol = Color4 0.93 0.79 0 solid
+      menu = "DUNGEONS OF WOR":"":"":items++["","","HIGH SCORE "++show score]
+
+  setAspectRatio aspectRatio 1
+
+  clear [ColorBuffer]
+  loadIdentity
+
+  texture Texture2D $= Enabled
+  forM_ (zip menu [-3..]) $ \(text,i) -> do
+    color $ if i == item then activeCol else textCol
+    displayText (0.5-(fromIntegral (length text)*4*charSize))
+                (0.5+charSize*(7*fromIntegral (length items-1-2*i)))
+                charSize text
+
+  renderOverlay rgbOverlay
+
+  flush
+  swapBuffers
+
+renderGame aspectRatio displayText rgbOverlay levelState levelCount scores lives = do
+  let curLevel = level levelState
+      (lw,lh) = fullLevelSize curLevel
+      height = fromIntegral lh / fromIntegral lw
+      magn = 1 / fromIntegral lw
+
+  setAspectRatio aspectRatio (getAspectRatio curLevel)
+
+  clear [ColorBuffer]
+  loadIdentity
+
+  renderHud displayText height scores lives (actors levelState) levelCount curLevel
+  preservingMatrix $ do
+    translate $ Vector3 0 hudHeight (0 :: GLfloat)
+    scale magn magn (1 :: GLfloat)
+
+    renderLevel curLevel
+    renderBullets (bullets levelState)
+    renderActors (actors levelState)
+
+  renderOverlay rgbOverlay
+
+  flush
+  swapBuffers
+
+renderOverlay rgbOverlay = do
+  texture Texture2D $= Enabled
+  textureBinding Texture2D $= Just rgbOverlay
+  blendFunc $= (Zero,SrcColor)
+  color $ Color4 1 1 1 solid
+  let pscale = 100
+  renderPrimitive Quads $ do
+    texCoord2 0 0
+    vertex3 0 0 0
+    texCoord2 pscale 0
+    vertex3 1 0 0
+    texCoord2 pscale pscale
+    vertex3 1 1 0
+    texCoord2 0 pscale
+    vertex3 0 1 0
+  blendFunc $= (SrcAlpha,OneMinusSrcAlpha)
+
+renderLevel level = do
+  let (lw,lh) = fullLevelSize level
+      height = fromIntegral lh / fromIntegral lw
+      entries = [((y,x),[]) | (_,y,x) <- entrances level]
+
+  texture Texture2D $= Disabled
+  color $ Color4 0.2 0.5 1 solid
+  forM_ (entries ++ assocs (legalMoves level)) $ \((y,x),ms) -> do
+    let xc = fromIntegral (x+1)
+        yc = fromIntegral (lh-y-2)
+    unless (North `elem` ms) $ drawRectangle xc (yc+0.95) 1 0.05
+    unless (South `elem` ms) $ drawRectangle xc yc 1 0.05
+    unless (East `elem` ms) $ drawRectangle (xc+0.95) yc 0.05 1
+    unless (West `elem` ms) $ drawRectangle xc yc 0.05 1
+
+renderActors as = do
+  let players = filter ((`elem` [BlueWorrior,YellowWorrior]) . actorType) as
+  texture Texture2D $= Enabled
+  color $ Color4 1 1 1 solid
+  forM_ as $ \a -> do
+    let V x y = A.position a
+        x' = fromIntegral x / fromIntegral fieldSize
+        y' = fromIntegral y / fromIntegral fieldSize
+        dist = case actorType a of
+          Garwor  -> 2*fieldSize
+          Thorwor -> fieldSize
+          _       -> maxBound
+        visible = any ((\(V px py) -> abs (x-px) < dist || abs (y-py) < dist) . A.position) players
+
+    when (visible && (not . null . animation) a) $
+      drawSprite (head (animation a)) (1.1+x') (1.1+y') 0.8 0.8 (facing a)
+
+renderBullets bs = do
+  texture Texture2D $= Disabled
+  color $ Color4 1 0.3 0.1 solid
+  forM_ bs $ \(_,V x y) -> do
+    let x' = fromIntegral x / fromIntegral fieldSize
+        y' = fromIntegral y / fromIntegral fieldSize
+    drawRectangle (1.45+x') (1.45+y') 0.1 0.1
+
+renderHud displayText height scores lives actors levelCount level = do
+  let r = Color4 1 0 0 solid
+      b = Color4 0.25 0.63 1 solid
+      y = Color4 0.93 0.79 0 solid
+      d = Color4 0 0 0 solid
+      charSize = 0.0028
+      radarTitle = if levelCount == 1 then "RADAR" else
+                     case levelName level of
+                       "pit"   -> "THE PIT"
+                       "arena" -> "THE ARENA"
+                       _       -> "DUNGEON " ++ show levelCount
+      (levelW,levelH) = levelSize level
+      scoreB = hudHeight / 4
+      scoreW = 0.3
+      scoreH = scoreB*3
+      radarB = charSize
+      radarW = radarF*fromIntegral levelW
+      radarH = hudHeight-radarB*4-charSize*10
+      radarF = radarH/fromIntegral levelH
+      snum1 = show (scores !! 0)
+      snum2 = show (scores !! 1)
+      lnum1 = show (lives !! 0)
+      lnum2 = show (lives !! 1)
+      numPlayers = length lives
+
+  texture Texture2D $= Disabled
+  color b
+  drawRectangle 0 0 scoreW scoreH
+  drawRectangle (0.5-radarW/2-radarB) 0 (radarW+radarB*2) (radarH+radarB*2)
+  color y
+  drawRectangle (1-scoreW) 0 scoreW scoreH
+  color d
+  drawRectangle scoreB scoreB (scoreW-2*scoreB) (scoreH-2*scoreB)
+  drawRectangle (1-scoreW+scoreB) scoreB (scoreW-2*scoreB) (scoreH-2*scoreB)
+  drawRectangle (0.5-radarW/2) radarB radarW radarH
+  forM_ actors $ \actor -> do
+    let (fx,fy) = fieldPos (position actor)
+        rx = 0.5-radarW/2+radarF*fromIntegral fx
+        ry = radarB+radarF*fromIntegral fy
+    case actorType actor of
+      Burwor -> color b >> drawRectangle rx ry radarF radarF
+      Garwor -> color y >> drawRectangle rx ry radarF radarF
+      Thorwor -> color r >> drawRectangle rx ry radarF radarF
+      _ -> return ()
+
+  texture Texture2D $= Enabled
+  color y
+  displayText (1-scoreB-(fromIntegral (length snum1)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize snum1
+  displayText (1-scoreW-3*radarB-(fromIntegral (length lnum1)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize lnum1
+  when (numPlayers > 1) $ do
+    color b
+    displayText (scoreW-scoreB-(fromIntegral (length snum2)*8*charSize)) (scoreB+scoreH/2-scoreB-5*charSize) charSize snum2
+    displayText (scoreW+3*radarB) (scoreB+scoreH/2-scoreB-5*charSize) charSize lnum2
+  color r
+  displayText (0.5-(fromIntegral (length radarTitle)*4*charSize)) (radarH+radarB*3) charSize radarTitle
+
+drawRectangle :: GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
+drawRectangle x y sx sy = renderPrimitive Quads $ mapM_ vertex
+  [Vertex3 x y 0, Vertex3 (x+sx) y 0, Vertex3 (x+sx) (y+sy) 0, Vertex3 x (y+sy) 0]
+
+drawSprite :: TextureObject -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> Direction -> IO ()
+drawSprite tid x y sx sy dir = do
+  let (u1,v1,u2,v2,u3,v3,u4,v4) = case dir of
+        North -> (1,1,1,0,0,0,0,1)
+        East  -> (1,1,0,1,0,0,1,0)
+        South -> (0,1,0,0,1,0,1,1)
+        West  -> (0,1,1,1,1,0,0,0)
+  textureBinding Texture2D $= Just tid
+  renderPrimitive Quads $ do
+    texCoord2 u1 v1
+    vertex3 x y 0
+    texCoord2 u2 v2
+    vertex3 (x+sx) y 0
+    texCoord2 u3 v3
+    vertex3 (x+sx) (y+sy) 0
+    texCoord2 u4 v4
+    vertex3 x (y+sy) 0
diff --git a/src/Sprites.hs b/src/Sprites.hs
--- a/src/Sprites.hs
+++ b/src/Sprites.hs
@@ -1,63 +1,63 @@
-module Sprites
-       ( SpriteStore
-       , parseSprites
-       ) where
-
-import Control.Applicative
-import Control.Monad.Fix
-import Control.Monad
-import Data.Array
-import Data.Word
-import Foreign.Marshal
-import Foreign.Ptr
-import Graphics.Rendering.OpenGL
-
-import GraphUtils
-
-type SpriteStore = [(String, [TextureObject])]
-
-parseSprites :: [String] -> IO SpriteStore
-parseSprites dat = do
-  let (coldat,sprdat) = span (\l -> not (null l) && (head l /= '[')) dat
-      colmap :: Array Char [Word8]
-      colmap = listArray (' ','~') (repeat [0,0,0,0]) // map mkcol coldat
-      mkcol (c:dat) = (c,[r,g,b,a])
-        where [(r,dat')] = reads dat
-              [(g,dat'')] = reads dat'
-              [(b,dat''')] = reads dat''
-              [(a,dat'''')] = reads dat'''
-
-  flip fix sprdat $ \addGroup dat ->
-    createSpriteGroup colmap dat >>= \res -> case res of
-      Just (name,g,dat') -> do
-        gs <- addGroup dat'
-        return ((name,g):gs)
-      Nothing -> return []
-
-createSpriteGroup colmap dat = do
-  let dat' = dropWhile null dat
-      gname = takeWhile (/=']') (tail (head dat'))
-
-  if null dat'
-    then return Nothing
-    else do
-    (sps,dat'') <- flip fix (tail dat',[]) $ \addSprites (dat,tids) ->
-      createSprite colmap dat >>= \res -> case res of
-        Just (tid,dat') -> do
-          addSprites (dat',tid:tids)
-        Nothing -> return (tids,dat)
-    return (Just (gname,reverse sps,dat''))
-
-createSprite colmap dat = do
-  let dat' = dropWhile null dat
-
-  if null dat' || head (head dat') /= '"'
-    then return Nothing
-    else do
-    let (spdat,dat'') = span (\l -> not (null l) && (head l == '"')) dat'
-        spdat' = explodeMatrix 3 (map (takeWhile (/='"') . tail) spdat)
-        spw = length (head spdat')
-        sph = length spdat'
-
-    tid <- createTexture spw sph False $ flip pokeArray [comp | lin <- spdat', pix <- lin, comp <- colmap ! pix]
-    return (Just (tid,dat''))
+module Sprites
+       ( SpriteStore
+       , parseSprites
+       ) where
+
+import Control.Applicative
+import Control.Monad.Fix
+import Control.Monad
+import Data.Array
+import Data.Word
+import Foreign.Marshal
+import Foreign.Ptr
+import Graphics.Rendering.OpenGL
+
+import GraphUtils
+
+type SpriteStore = [(String, [TextureObject])]
+
+parseSprites :: [String] -> IO SpriteStore
+parseSprites dat = do
+  let (coldat,sprdat) = span (\l -> not (null l) && (head l /= '[')) dat
+      colmap :: Array Char [Word8]
+      colmap = listArray (' ','~') (repeat [0,0,0,0]) // map mkcol coldat
+      mkcol (c:dat) = (c,[r,g,b,a])
+        where [(r,dat')] = reads dat
+              [(g,dat'')] = reads dat'
+              [(b,dat''')] = reads dat''
+              [(a,dat'''')] = reads dat'''
+
+  flip fix sprdat $ \addGroup dat ->
+    createSpriteGroup colmap dat >>= \res -> case res of
+      Just (name,g,dat') -> do
+        gs <- addGroup dat'
+        return ((name,g):gs)
+      Nothing -> return []
+
+createSpriteGroup colmap dat = do
+  let dat' = dropWhile null dat
+      gname = takeWhile (/=']') (tail (head dat'))
+
+  if null dat'
+    then return Nothing
+    else do
+    (sps,dat'') <- flip fix (tail dat',[]) $ \addSprites (dat,tids) ->
+      createSprite colmap dat >>= \res -> case res of
+        Just (tid,dat') -> do
+          addSprites (dat',tid:tids)
+        Nothing -> return (tids,dat)
+    return (Just (gname,reverse sps,dat''))
+
+createSprite colmap dat = do
+  let dat' = dropWhile null dat
+
+  if null dat' || head (head dat') /= '"'
+    then return Nothing
+    else do
+    let (spdat,dat'') = span (\l -> not (null l) && (head l == '"')) dat'
+        spdat' = explodeMatrix 3 (map (takeWhile (/='"') . tail) spdat)
+        spw = length (head spdat')
+        sph = length spdat'
+
+    tid <- createTexture spw sph False $ flip pokeArray [comp | lin <- spdat', pix <- lin, comp <- colmap ! pix]
+    return (Just (tid,dat''))
diff --git a/src/Text.hs b/src/Text.hs
--- a/src/Text.hs
+++ b/src/Text.hs
@@ -1,57 +1,57 @@
-module Text
-       ( loadCharset
-       , displayString
-       ) where
-
-import Control.Applicative
-import Control.Monad
-import Data.Array
-import Data.List
-import Data.Word
-import Foreign.Marshal
-import Foreign.Ptr
-import Graphics.Rendering.OpenGL
-
-import GraphUtils
-
-loadCharset file = do
-  dat <- lines <$> readFile file
-  let cs = unfoldr parseChar dat
-      cpos = map (\n -> (n `mod` 8,n `div` 8)) [0..]
-      cdat = array (' ','Z') (zip (map fst cs) cpos)
-
-      mkpix '#' = [255,255,255,255]
-      mkpix _   = [255,255,255,0]
-
-  tid <- createTexture 256 256 False $ \tex -> do
-    pokeArray tex $ concat (replicate (256*256) [255,255,255,0])
-    forM_ (zip cs cpos) $ \((_,cimg),(x,y)) -> do
-      forM_ (zip cimg [0..]) $ \(crow,ry) -> pokeArray (advancePtr tex ((x*32+1)*4+(y*32+1+ry)*256*4)) (concatMap mkpix crow)
-
-  return (tid,cdat)
-
-parseChar dat = if null dat' then Nothing else Just ((c,explodeMatrix 3 img),dat'')
-  where dat' = dropWhile null dat
-        c = head (head dat')
-        (img,dat'') = span (not . null) (tail dat')
-
-displayString tid cdat x y m s = do
-  textureBinding Texture2D $= Just tid
-
-  let displayChar c x = do
-        let (cx,cy) = cdat ! c
-            u = fromIntegral (cx*32+1)/256
-            v = fromIntegral (cy*32+1)/256
-        texCoord2 u (v+ch)
-        vertex3 x y 0
-        texCoord2 (u+cw) (v+ch)
-        vertex3 (x+8*m) y 0
-        texCoord2 (u+cw) v
-        vertex3 (x+8*m) (y+10*m) 0
-        texCoord2 u v
-        vertex3 x (y+10*m) 0
-      cw = 24/256
-      ch = 30/256
-
-  renderPrimitive Quads $ forM_ (zip s [0..]) $ \(c,i) ->
-    displayChar c (x+i*8*m)
+module Text
+       ( loadCharset
+       , displayString
+       ) where
+
+import Control.Applicative
+import Control.Monad
+import Data.Array
+import Data.List
+import Data.Word
+import Foreign.Marshal
+import Foreign.Ptr
+import Graphics.Rendering.OpenGL
+
+import GraphUtils
+
+loadCharset file = do
+  dat <- lines <$> readFile file
+  let cs = unfoldr parseChar dat
+      cpos = map (\n -> (n `mod` 8,n `div` 8)) [0..]
+      cdat = array (' ','Z') (zip (map fst cs) cpos)
+
+      mkpix '#' = [255,255,255,255]
+      mkpix _   = [255,255,255,0]
+
+  tid <- createTexture 256 256 False $ \tex -> do
+    pokeArray tex $ concat (replicate (256*256) [255,255,255,0])
+    forM_ (zip cs cpos) $ \((_,cimg),(x,y)) -> do
+      forM_ (zip cimg [0..]) $ \(crow,ry) -> pokeArray (advancePtr tex ((x*32+1)*4+(y*32+1+ry)*256*4)) (concatMap mkpix crow)
+
+  return (tid,cdat)
+
+parseChar dat = if null dat' then Nothing else Just ((c,explodeMatrix 3 img),dat'')
+  where dat' = dropWhile null dat
+        c = head (head dat')
+        (img,dat'') = span (not . null) (tail dat')
+
+displayString tid cdat x y m s = do
+  textureBinding Texture2D $= Just tid
+
+  let displayChar c x = do
+        let (cx,cy) = cdat ! c
+            u = fromIntegral (cx*32+1)/256
+            v = fromIntegral (cy*32+1)/256
+        texCoord2 u (v+ch)
+        vertex3 x y 0
+        texCoord2 (u+cw) (v+ch)
+        vertex3 (x+8*m) y 0
+        texCoord2 (u+cw) v
+        vertex3 (x+8*m) (y+10*m) 0
+        texCoord2 u v
+        vertex3 x (y+10*m) 0
+      cw = 24/256
+      ch = 30/256
+
+  renderPrimitive Quads $ forM_ (zip s [0..]) $ \(c,i) ->
+    displayChar c (x+i*8*m)
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -1,43 +1,43 @@
-{-# LANGUAGE RecursiveDo #-}
-
-module Utils where
-
-import Control.Applicative
-import Control.Monad
-import Control.Monad.Fix
-import Data.Maybe
-import Data.Traversable hiding (sequence)
-import FRP.Elerea.Simple
-import System.Random.Mersenne
-
-infix 2 -->
-
-edge s = do
-  s' <- delay False s
-  return $ s' >>= \x -> if x then return False else s
-
-x0 --> s = transfer x0 store s
-    where store Nothing  x = x
-          store (Just x) _ = x
-
-collection source isAlive = mdo
-  sig <- delay [] (map snd <$> collWithVals')
-  coll <- memo (liftA2 (++) source sig)
-  let collWithVals = zip <$> (sequence =<< coll) <*> coll
-  collWithVals' <- memo (filter <$> ((.fst) <$> isAlive) <*> collWithVals)
-  return $ map fst <$> collWithVals'
-
-switcher gen = mdo
-  trig <- memo (snd =<< pw)
-  trig' <- delay True trig
-  ss <- generator (toMaybe <$> trig' <*> gen)
-  pw <- undefined --> ss
-  return (fst =<< pw,trig)
-
-toMaybe b s = if b then Just <$> s else pure Nothing
-
-noise :: MTRandom a => SignalGen (Signal a)
-noise = effectful randomIO
-
-getRandom :: MTRandom a => SignalGen a
+{-# LANGUAGE RecursiveDo #-}
+
+module Utils where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Data.Maybe
+import Data.Traversable hiding (sequence)
+import FRP.Elerea.Simple
+import System.Random.Mersenne
+
+infix 2 -->
+
+edge s = do
+  s' <- delay False s
+  return $ s' >>= \x -> if x then return False else s
+
+x0 --> s = transfer x0 store s
+    where store Nothing  x = x
+          store (Just x) _ = x
+
+collection source isAlive = mdo
+  sig <- delay [] (map snd <$> collWithVals')
+  coll <- memo (liftA2 (++) source sig)
+  let collWithVals = zip <$> (sequence =<< coll) <*> coll
+  collWithVals' <- memo (filter <$> ((.fst) <$> isAlive) <*> collWithVals)
+  return $ map fst <$> collWithVals'
+
+switcher gen = mdo
+  trig <- memo (snd =<< pw)
+  trig' <- delay True trig
+  ss <- generator (toMaybe <$> trig' <*> gen)
+  pw <- undefined --> ss
+  return (fst =<< pw,trig)
+
+toMaybe b s = if b then Just <$> s else pure Nothing
+
+noise :: MTRandom a => SignalGen (Signal a)
+noise = effectful randomIO
+
+getRandom :: MTRandom a => SignalGen a
 getRandom = execute randomIO
diff --git a/src/Vector.hs b/src/Vector.hs
--- a/src/Vector.hs
+++ b/src/Vector.hs
@@ -1,11 +1,11 @@
-module Vector where
-
-data Vec = V !Int !Int deriving (Show, Eq)
-
-instance Num Vec where
-  V x1 y1 + V x2 y2 = V (x1+x2) (y1+y2)
-  V x1 y1 - V x2 y2 = V (x1-x2) (y1-y2)
-  V x1 y1 * V x2 y2 = V (x1*x2) (y1*y2)
-  abs (V x y) = V (abs x) (abs y)
-  signum (V x y) = V (signum x) (signum y)
-  fromInteger x = V (fromInteger x) (fromInteger x)
+module Vector where
+
+data Vec = V !Int !Int deriving (Show, Eq)
+
+instance Num Vec where
+  V x1 y1 + V x2 y2 = V (x1+x2) (y1+y2)
+  V x1 y1 - V x2 y2 = V (x1-x2) (y1-y2)
+  V x1 y1 * V x2 y2 = V (x1*x2) (y1*y2)
+  abs (V x y) = V (abs x) (abs y)
+  signum (V x y) = V (signum x) (signum y)
+  fromInteger x = V (fromInteger x) (fromInteger x)
