I am a F# apprentice. The best way to learn new language is to do some project. That’s why I have started to code one game idea that was following me for some time.

Core concept:

  • sci-fi setting
  • roguelike
  • inspired by:
    • dwarf fortress
    • prison architect
    • cataclysm dda

Because I don’t care about the graphics but the game-play, the graphic I am going to use will be an ASCII styles tile set. You know symbols, characters, letters and some simple graphic, just like in old MUD games.

For graphic layer, I am going to use SFML and it’s .NET wrapper. It’s quite good and I know a bit about it. In the past I have been using SDL wrapper which was also fine. At the beginning I am mostly going to focus on 2D tile rendering and some ray casting to calculate field of view. I really like the way it’s done in Cataclysm DDA, so I ll try to emulate it.

Apart from coding the game and its logic, the most difficult part will be to use F#. I am a little worried about its stateless world. I have heard about monads and how you can manage state with them, but still its going to be difficult for apprentice like me.

To start with something, I have decided to do my first simple game loop and render window.

[<EntryPoint>]
let main argv = 

    let mainWindow = new RenderWindow(new VideoMode(600ul, 600ul), "EmptySpace")
    mainWindow.SetFramerateLimit(40ul);
    mainWindow.Closed.AddHandler(fun sender args -> (sender :?> RenderWindow).Close())

    let rec mainLoop() = 
        mainWindow.Clear()
        mainWindow.DispatchEvents()
        mainWindow.Display()

        match mainWindow.IsOpen() with
        | true ->  mainLoop() |> ignore
        | false ->  ()
    
    mainLoop()

    0

Couple of interesting things in this code.

":?>" operator

If I have some class that inherits the System.Object ( Default behavior in .NET ).

”:?>” downcast - it will cast Object to Something. This operation is performed on run time.

The ":?>" operator performs a dynamic cast, which means that the success of the cast is determined at run time. A cast that uses the ":?>" operator is not checked at compile time; but at run time, an attempt is made to cast to the specified type.

”:>” upcast - it will cast Something to Object. This operation is performed on compile time.

The ":>" operator performs a static cast, which means that the success of the cast is determined at compile time. If a cast that uses ":>" compiles successfully, it is a valid cast and has no chance of failure at run time.

More about casting in F# world

Pattern matching ( F# switch )

 
  match mainWindow.IsOpen() with
     | true ->  mainLoop() |> ignore
     | false -> ()

From my understating it’s something like a switch but with more powerful options and possibilities. My example is a simple true, false switch.

() is an empty method just to do nothing and stop recurrence.

> is a pipe lining operator, concept i know from the unix world, ignore is just information that i want to ignore the value that mainLoop() is returning.

More about pattern matching

Recurrent loop - rec keyword

The Game Loop has to be infinite. In functional approach you don’t use loops, like while(true), instead you have to use recurrence. In C# you can just call function from within the function. In F# you can do the same, however you need to mark function with rec keyword ? Why ? The answer is complex and if you want to know it check this link and this one

Share