haskell roguelike #1: setup

let's make a roguelike in haskell! haskell will be interesting to implement a roguelike in, since it's quite different from the usual roguelike languages (c++, c, python, etc). note that this tutorial is just sort of written as I go along, so it might change a lot or vanish if I ever give up on the project. also, the tutorial assumes you have basic haskell knowledge (at least as much knowledge as I have, which isn't much) and are familiar with what a roguelike is.

setting up the project (using nix)
let's start by setting up the project. I use the nix package manager, which works really well for avoiding dependency conflicts with haskell packages, so that's what this tutorial will use.

first, choose a name for the roguelike. this tutorial will use the name "toast," which is completely arbitrary. so anytime you see "toast" in the code, just replace it with the name you want. on that note, let's start:

mkdir toast
cd toast
cabal init
        
this creates a new file called toast.cabal. that file will look something like this:
cabal-version:       >=1.10
-- Initial package description 'toast.cabal' generated by 'cabal init'.
-- For further documentation, see http://haskell.org/cabal/users-guide/

    name:                toast
version:             0.1.0.0
-- synopsis:
-- description:
-- bug-reports:
-- license:          
license-file:        LICENSE
author:              your-name
maintainer:          your-email
-- copyright:
-- category:
build-type:          Simple
extra-source-files:  CHANGELOG.md

executable toast
main-is:             Main.hs
-- other-modules:
-- other-extensions:
build-depends:       base >=4.12 && <4.13
hs-source-dirs:
default-language:    Haskell2010
        
you can fill in the metadata fields like license if you want, but that's not particularly crucial. next, we'll need to generate a .nix file for the project, which is basically a specification that tells the nix package manager what dependencies the project has, so it can automatically deal with versioning. as a bonus, the .nix file also tells nix how to build our project, so in general it will make life a lot easier for us. run the command
cabal2nix . > toast.nix
        
to generate the .nix file from the .cabal file we just created. if you're interested, the file looks like this:
{ mkDerivation, base, stdenv }:
mkDerivation {
  pname = "toast";
  version = "0.1.0.0";
  src = ./.;
  isLibrary = false;
  isExecutable = true;
  executableHaskellDepends = [ base ];
  description = "";
  license = "";
}
        
we're not quite done with setup yet. next, create a release.nix file, which contains code to call the toast.nix file:
let pkgs = import <nixpkgs> {};
in rec {
  toast = pkgs.haskellPackages.callPackage ./toast.nix { };
}
        
this wraps our package in a way that allows us to build it. the last .nix file we'll need to make is shell.nix, which tells nix how to create a shell environment from our package definition:
(import ./release.nix).toast.env
        

building
now to build it! simply run
nix-build release.nix
          
and nix will build the package and put the result in the result/bin directory. then, you can do
./result/bin/toast
          
to run it. if you ever need to drop into a shell where all the dependencies are installed (say, in order to run cabal repl), run
nix-shell
          

wrapping up
that's all for part 1. in this part, you should've learned how to: I hope this helped, and I hope you're still interested in what's to come! in the next part, we'll be discussing how to plan out the project.