I want to code a game in Haskell where every iteration of the loop computes the state of the world. I thought I should create a function:
gameLoop :: World -> World
-- ...
and have main :: IO ()
call it:
main = do
gameLoop -- ...
But the problem is that I'm missing some fundamental understanding of how to wrap the gameLoop
function so that it returns main
's parameter value.
How would one go about creating a game loop in Haskell?
Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it. That's why there are no while loops or for loops in Haskell and instead we many times have to use recursion to declare what something is.
Making a game in Haskell is a pioneering process. Despite the fact that there's a page on the wiki and a full subreddit dedicated to the purpose of making a game in this beautiful language, not many people have actually succeeded making anything close to what current game developers can already achieve.
The game structure The game loop is a sequence of processes that run continuously as long as the game is running. The three main processes that occur in the game loop are input, update, and render. The input process is how the player controls the game.
The game loop is the overall flow control for the entire game program. It's a loop because the game keeps doing a series of actions over and over again until the user quits. Each iteration of the game loop is known as a frame.
You'll probably want something like this
import Control.Monad.Loops
main = iterateM_
(\w -> displayWorld w >> return (gameLoop w))
initWorld
-- iterateM_ ((>>) <$> displayWorld <*> return . gameLoop) initWorld
Or if you don't want to use the whole monad-loops package (even though it rocks)
main = loop initWorld
where loop w = displayWorld w >> loop (gameLoop w)
Basically you're just drawing the world, then looping again to with the next state.
More likely you want something like this though
-- False when the user wants to exit the game
keepGoing :: World -> Bool
main = iterateUntilM_ keepGoing displayLoop initWorld
where displayLoop w = displayWorld w >> return (gameLoop w)
Since otherwise you can't stop :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With