Using F# instead of C#?

I’m interested in using F#. I guess at some point in the future, Xenko will support F# right out of the box.

To get F# to work. I tried two things so far.

  • I replaced the [project name].Game csproj file with a fsproj file.
  • I created a new F# project added to the solution.

The first approach gave me Asset Compiler errors. Seems Asset Compiler is still looking for a .csproj file:

The command ““C:\Program Files\Silicon Studio\Xenko\GamePackages\Xenko.1.9.2-beta\Bin\Windows-Direct3D11\SiliconStudio.Assets.CompilerClient.exe” --disable-auto-compile --project-configuration “Debug” --platform=Windows --profile=Windows --project-configuration=Debug --output-path=“D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Bin\Windows\Debug\data” --build-path=“D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Windows…\obj\data” --package-file=“D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Windows…\Xenko FSharp.xkpkg” --log-pipe=”"" exited with code 1.

[AssetCompiler] Unexpected error while loading project [D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Game\ Xenko FSharp.Game.csproj] or assembly reference []. Exception: The project file could not be loaded. Could not find file ‘D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Game\Xenko FSharp.Game.csproj’. D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Game\Xenko FSharp.Game.csproj

[AssetCompiler] Error while loading package [SiliconStudio.Assets.Package]. Exception: The project file could not be loaded. Could not find file ‘D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Game\Xenko FSharp.Game.csproj’. D:\Americanum Mentis\Tech Projects\Xenko FSharp\Xenko FSharp\Xenko FSharp.Game\Xenko FSharp.Game.csproj

The problem with the second approach is, that I can’t use any F# code from the C# project. Because the C# game project is a portable class library. And they can’t reference normal class libraries such as the F# project I added. There are portable class libraries in Visual Studio for F#. They are tagged with Xamarin, Silverlight and UWP, but they can’t be referenced either. I can see C# libraries tagged with .Net Core and Portable. But there is no such thing for F# for some reason.

Beside of the problem to build successfully. I also suspect that Game Studio won’t show any F# components in its editor? Unity got a simple way of supporting F#/Native code. In Unity I only have to add an assembly that was built with F# code and that’s all. Unity would show the components in the editor so I can attach them to an entity. To solve this problem, I could use C# wrappers around F#.

2 Likes

To resolve the both problems of my two trials. I thought I just would make Xenko to generate an F# project for game logic in the first place. I have never worked with build targets before, or messed around with assemblies references or Xenko itself before. So fill free to comment if you know something.

A Xenko generated FS project should fix the ‘csproj file not found’ and the conflict between normal libraries and portable C#/F# libraries. I can’t foresee if Xenko Game Studio will be able to list the scripts though. Seems certain to me that without modifying the source of Game Studio, the .fs source files inside the asset browser won’t show for sure. Only the Add Component drop down list may list F# written components, and that only if it doesn’t require actual .fs source files to understand that there are components to look for in the first place.

In trying to make Xenko generate a F# project, I noticed a funky thing at Xenko’s side.

I found that the generation of the portable C# file goes over a v5.0/v4.6 build targets set. And some assemblies files are copied over from CoreCLR into the Xenko folder from its original paths. There is a Readme.dm file at the location C:\Program Files\Silicon Studio\Xenko\GamePackages\Xenko.1.9.2-beta\deps\CoreFX\configs, it says:

Description

The goal of this configuration file is to make MSBuild think you are compiling against the PCL but actually you are compiling against the set of reference assemblies supplied in this project.

To do that we supply our own version of the Portable C# targets. It is a copy of the Microsoft supplied one at C:\Program Files (x86)\MSBuild\Microsoft\Portable\v5.0\Microsoft.Portable.CSharp.targets where we added in addition to the existing imports some definitions for identifying our .NET target, and we override _CheckForInvalidTargetFrameworkProfile to do nothing since CoreCLR has no profile.

Implementation notes

Before including Microsoft.Portable.Common.targets we define the Framework version to 4.6, as the 5.0 folder from Microsoft is empty and would not include our assemblies. After inclusion, we update the version to 5.0 as expected.

If you find a better way to set this up without having to copy the Microsoft supplied MS Build targets, feel free to send a pull request.

I noticed that there are no F# target files inside MSBuild\Microsoft\Portable\v5.0 (or v4.6, 4.5, 4.0), there are only targets for Visual Basic and C#. However, MSBuild\Microsoft\Visual Studio\v14.0\FSharp, got portable targets with paths to the Microsoft SDKs\F#\4.0\Framework\v4.0. Also there is no FSharp assembly inside Xenko’s own CoreFX\v5.0 folder. But I’ve seen an FSharp.Core assembly somewhere else.

I hope a targets/assemblies stitching works out in the end. :slight_smile:

To make sure that I didn’t miss anything with the portable F# libraries that can be found in the VS project creation window itself, I checked again. And the error messages is always the same: Unable to add a reference to project ‘[project name]’. Portable Library projects can only reference other Portable Library projects and assemblies.

I tried these F# projects to add to Xenko’s C# game logic project:

  • Portable Library (.NET 4.5, Windows Store, Silverlight 5, Xamarin)
  • Portable Library (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin)
  • Portable Library (.NET 4.5, Windows Store Windows Phone 8.1,Windows Phone 8 Silverlight, Xamarin)
  • Portable Library (.NET 4.5, Windows Store, Xamarin)

There is no .Net Core or other portable projects for F#, unlike for C#. .Net Core SDKs 1.0.1. and 1.1.0 are installed of course.

Any portable F# projected created with Visual Studio, is not having the (portable) tag on its name in the solution panel. So, safe to say that this is the reason why Xenko’s game logic C# project that got such a tag, is not wanting to make any references. I don’t why the tag is missing for the F# project, though. I changed the TargetFrameWorkVersion and TargetFrameWorkProfile of the F# project, to the same values of the C# projects. But still no (portable) tag.

I’m trying to make Xenko Studio to use a normal FSharp project as a package, by adding the project to the .XKPKG file. It worked with a normal non-portable CSharp project, that I added via VS17. However, a FSharp project is causing problems. For some reason $(FSharpTargetsPath) seem to be empty.

Error: Unexpected error while loading project [D:_ Rarum Mentis\Tech Projects\XenkoFSharp\XenkoFSharp\Library1\Library1.fsproj] or assembly reference []. Microsoft.Build.Exceptions.InvalidProjectFileException: The value “” of the “Project” attribute in element is invalid. Parameter “path” cannot have zero length.

And if I add an actual path: “C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\Microsoft.FSharp.targets” Then I get this:

If I compile via VS17, the later problem is only with Xenko Studio, not with VS17. So in VS it all works and even starts the game.

1 Like

By the way, it turned out that the error “Unable to add a reference to project ‘[project name]’. Portable Library projects can only reference other Portable Library projects and assemblies.”, isn’t Xenko related. It’s an M$ problem, since the same error occurs even with a normal VS solution created with VS17 projects.

Two years later, what’s the status on this? I’ve graduated to coding .NET applications exclusively in F# (when I can), and I’m seeing more and more programmers wake up to how much better F# is than C#. Unity has a respectable F# sub-community, and I’ve gotten a .NET Standard 2.0 logic library that I wrote entirely in F# to work flawlessly in a Unity game project.

Is anyone using F# to make Xenko a game? What kind of set-up is required? Is it totally F#, or is some C# still involved?

I think it’s no more a case. Since now we can totally compile and run the project in VS now.
So you can make an F# background dll to support the C# front end.

However, I don’t think it’s a good idea to make an F# FSM like a game, doing stateless data processing task fits better. You need to give up immutability to make it, then the only advantage rest is ADT (and tagged union will be supported in C#). I code in OCaml/CPP in my work and I do F#/C# projects personally.

I’m not talking only about the functional coding paradigm that F# supports. Much of the functional way of programming logic is doable with languages that weren’t designed for that specific purpose, anyway; C# itself has built up a decent collection of functionally-oriented features over the years (LINQ, Action and Func types, Tuple types, lambda expressions, etc.), despite being designed purely as an OO language.

I’m talking largely about F# being better even for OO programming. F# is multi-paradigm, and it offers far cleaner syntax and much more succinct code than C#, thanks to features like type inference, pipe-forwarding, being expression oriented (no return statements unless you’re employing computation expressions), and scoping by white space instead of delimiting characters (like C/C++/C#'s braces).

F#'s way of coding asynchronous operations is also much leaner and more intuitively expressed than the same in C#, with the async workflow and robust collection of functions designed to work on Async values. F# is much better suited for parallel programming, too; Luca Bolognese gave a great presentation that demonstrated, about 52 minutes into it, just how much better than C# F# is at breaking down tasks into multi-threaded operations.

That’s all just for starters. F# is just so much better than C# in nearly every way, not just for functional progamming, but for OO programming as well. More and more .NET programmers seem to be coming around to it.

If you are talking about OO, you must have known façade pattern, so any problem can be solved by indirection.

I never do OO in OCaml, and only do OO with F# only when I have to. (e.g when doing WPF projects)