Godot 4 and F#

Update: After beginning to make a game, it turned out not to be as straightfoward as this post implies. Primarily because Godot 4 requires that the C# class be a partial class extending the corresponding Godot entity. F# doesn't have a direct translation of partial classes as far as I know. Although following the instructions in this post will get F# into the project, so far I've had to use F# for utilities and logic by consuming them in the C# code, rather than doing all of the lifting in F# (which you'd be able to do if you could extend the Godot entity directly from an F# class). I'll be sure to update again if I find a better way.

Original Post: Godot 4 is finally in beta and the .NET 6 builds are available for download. Previously I did a post on the convoluted process of adding F# to a Godot 3 project, but now I'm happy to say that adding F# is extremely simple. The only thing that would make it simpler is if you could officially initialize an F# script from the Godot UI.

Here are the steps to gettings started with an F# script:

  • Download the Godot 4 beta here
  • Open it and create a new project
  • Add a node to the scene (in my case I added a node2d)
  • Right-click on the node and select "attach script"
  • Select C# as the language and leave the other options as the defaults
  • Adding the script will have created a .NET solution file. Open Rider or your IDE of choice and open that solution file
  • Right-click on the solution in the left panel and select "Add Project"
  • Create a blank F# class library. I typically name my project something along the lines of "FsharpScripting", "[GameName]FS", or "[Scene]FS".
  • Right-click on the C# project in the left panel and select "Add Reference". Add the F# library you just created.
  • Open the .fsproj file and change the parent <Project> element to <Project Sdk="Godot.NET.Sdk/4.0.0-beta1">. This will allow you to import Godot modules into the F# modules.

Now you are all set. You can write your code in F# instead of C#. If you go back to the .cs file that Godot generated, it will look something like this:

using Godot;
using System;

public partial class node_2d : Node2D
{
	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
	}

	// Called every frame. 'delta' is the elapsed time since the previous frame.
	public override void _Process(double delta)
	{
	}
}

This class extends Godot's Node2D class. We can do the same in F#. Create a new file in the F# library called Node2D.fs and fill it with the following:

namespace FSharpScripting

open Godot

type MyNode () =
    inherit Node2D()
    
    override this._Ready() =
        ()
        
    override this._Process(delta) =
        ()

Then go back to the C# file and change it so that it simply calls the F# code:

using FsharpScripting;

public partial class node_2d : MyNode { }

Done! Now you can go back into Godot and play the scene and it will build and play without errors, although nothing will happen because there is no logic yet. From here on out your MO will be attaching C# scripts to nodes, and those C# scripts will simply extend and call F# files which have the real logic.