Wolfenstein 3D in Haskell. Inspired by John Carmack's Quakecon 2013 Talk and mentions of trying to implement games (and Wolf3D in particular) in functional programming/Haskell.
The implementation aims to use similar runtime data structures to the original source. I want to get a better understanding of how the original works and also reap the performance rewards (my naive attempts at a ray caster before performed badly). Also I hope this helps getting the same feel as the original.
This is a work in progress and is still in early stages.
- Stack (tested with 1.9.1-1.9.3)
- SDL2 (tested with 2.0.8-2.0.9)
- SDL2 Image (tested with 2.0.4)
- SDL2 TTF (tested with 2.0.14)
stack setup
stack build --pedantic
stack exec wolf3d
or
stack exec wolf3d-debug
stack repl
stack test --pedantic
Or continuous:
stack test --pedantic --file-watch
-
have press m to toggle map for debug
-
move sprites forward a bit. This was fudged in original:
-
id system for items
-
multi engine approach outlined in first 60 or so slides of https://www.slideshare.net/naughty_dog/multiprocessor-game-loops-lessons-from-uncharted-2-among-thieves
-
static sprite targets that hero can shoot and kill
-
SimItem infrastructure - Update each item to produce events, process those events which generate new events
-
Split SDL dependency into own module
- split Display into multiple modules
- merge UI into display? - simplifies some things like disposing and setting up renderer
-
rendering alternatives
- https://github.com/bkaradzic/bgfx looks good for rendering
- OpenGL renderer - https://hackage.haskell.org/package/OpenGL
- See https://github.com/jxv/sdl2-fps
- SoftwareRenderer provides much better performance (in createRenderer)
- try using SDL.opengl ?
- do some research on spritesheets, is it faster?
- abstract textures into class - TextureSource, AnimatedTextureSource, etc.
-
Hold multiple weapons and change between them with key presses
-
read levels from shareware files (see https://devinsmith.net/backups/bruce/wolf3d.html)
-
shoot Uzi
-
animate Uzi
-
difference for pistol and uzi - auto vs semi auto
-
Structure cabal project in such a way that modules not exposed to main can still be exposed to test
- Do general deeper research into cabal project and possibilities - multiple libraries?
-
Dont render hidden sprites
- only render within field of view bounds
- only render in front of walls
-
sprite items stop hero moving movement
-
pickup items
-
doors
-
enemy
-
secret doors
-
All events together at the end of game loop passed to audio handler, which plays audio
-
mouse look horizontal
-
mouse look up/down (move projection plane up/down)
-
SDL dispose textures at the end
-
Example world that shows off diagonal walls, etc
-
Console menu system at start
- better index for weapon animation data
- Optimise render - a lot of calculations can be done once
- Try reading original data file? See carmackExpand in wolf3d-html. Or maybe just use the format from wolf3d-html