Introduction
I like F# and functional programming (FP) but I also happen to like video games and making them, which of course leads to the natural question: Can F# be used for game development?
As someone who has dabbled with game development and is currently delving into functional programming, I find it a bit conflicting. Game development follows the Object Oriented paradigm (OOP), every major framework or engine dedicate to game development uses an OOP language (e.g Unity, Godot and Unreal Engine) and it makes sense, when developing a game we are thinking in terms of players, enemies and worlds, these are things with attributes and actions so it feels more fitting in OOP. FP tends to be more abstract, if we find ourselves needing to process data or scrape a website OOP doesn't make sense anymore and FP seems like a better fit.
However, it might be worth exploring solutions that allow us to use the benefits of working in a functional paradigm and, at the same time, develop games in a manner that is both productive and easy to understand. F# is a language in the .NET ecosystem, allowing for easier communication between the other languages in .NET, like the programming language C#. This language can be found in many popular game engines, like Unity and Godot and because these two languages are in the same ecosystem there are tools/ways allowing the use of F#. We will explore these and try to figure out if game development in F# is a possibility.
Game engines
Unity
Unity uses scripts (C# files) to create behaviours for its objects. An object in Unity that acts like a player character will have a script attached to it that could allow it to move, shoot and collide or do any other behaviour the C# script has been programmed to do.
There are a couple of approaches that can be found on the internet. Jackson Dunstan in his blog provided a way by making use of FSharp.Core.dll. More recently, channel 7sharp9 started a youtube series where they have added F# to Unity. Their method relies on F# being compiled into assembly and Unity loading the assembly which tends to be slower than loading a C# script.
One more interesting find is the journey of four senior undergraduate students developing a game with Unity and F# for their senior project. Although a bit older it provides an overview of a team that tried to build a full game. They concluded that after one year of working with Unity they would not recommend using F# and that it's a novelty at best. The imperative and mutatable states of Unity's design led to recreating a lot of Unity behaviour from scratch and what they managed to use from Unity proved more trouble than it was worth.
Godot
Godot behaves similarly to Unity, it also adds behaviour using scripts and can understand C#. The way we write behaviour using F# is by using C# as a conduit, everything written in F# can be used in a C# file that in turn will be used by Godot. An example of this implementation can be found in Lars Kokemohr's blog. A video explanation with a similar method can be found on HAMY LABS's channel that contains a bit more explanation.
Personally, I would have liked if these guides would show more examples so I took a shot at it. This is how we can write the "Process" function that is used by Godot to run every second (or 60 frames) and some additional code to make the object move based on key presses:
override this._Process(delta : float32) =
let mutable (speed : float32) = 3.0f
if Input.IsKeyPressed (int KeyList.W)
then this.Position <- this.Position + new Vector2(0.0f, (- speed))
if Input.IsKeyPressed (int KeyList.S)
then this.Position <- this.Position + new Vector2(0.0f, speed)
if Input.IsKeyPressed (int KeyList.A)
then this.Position <- this.Position + new Vector2((- speed), 0.0f)
if Input.IsKeyPressed (int KeyList.D)
then this.Position <- this.Position + new Vector2(speed, 0.0f)
()
Writing F# code to work with Godot seems to have similar issues that happened in Unity. We are still using mutable states and inheritance which take from the F# purity. However, with Godot I found it much easier to apply my F# code albeit it still seems to be a bit of an effort, every F# file we create must have an equivalent C# file.
Nu
Nu is the special game engine on this list. It claims to be the world's first practical functional 2D and 3D (still a WIP) cross-platform game engine built in F#. Running on the .NET Framework and Windows, it uses the Elm-style programming and can be configured to run in an immutable mode but for better performance, Nu is configured to run with mutation under the hood.
The Nu project seems to be well-maintained and has in-depth documentation. The Nu game engine would deserve its own blog but right now it seems to fit our needs for an FP paradigm and being able to create a proper game.
Conclusion
We had a look at some popular game engines within the game industry, as well as a quick look at F# game engine. What is the conclusion? Game development with F# is a difficult process, popular game engines are not reliable and other engines specific to F# like the Nu game engine are limited. However, the Nu game engine has potential and it's worth exploring it more, possibly in another blog. I hope you enjoyed this short overview of game development with F# 🙂