Hello! My name is Jack Palevich, and I am a developer at Microsoft. In my day job I work on graphics libraries and tools for the Xbox 360, but as a hobby I like to write video games.
Most games are written in C or C++, with some migration to C#. While those are very good languages, I'm always on the lookout for something new. I see a lot of potential in F#. It's based on OCaml, which seems to have been used successfully in several small hobby game engines. To help myself learn F# I wrote a simple 2D video game in F#.
(I'm having trouble attaching the ZIP file to this message. Look for a follow-up message that includes the zip file.)
(Below are some excerpts from the manual that's included in the ZIP file.)
Welcome to Dandy Dungeon
Dandy Dungeon is a 1-to-4 player cooperative action adventure game. I originally wrote it in 1983 in 6502 assembly language for the Atari 800. Since then I've ported it to different environments and languages. Its graphics are quite primitive by modern standards, but the gameplay is still enjoyable, especially when two or more people are playing.
Comparing Implementation Languages
For fun I have recently implemented Dandy in several different computer languages. You might think it’s a little bit obsessive-compulsive to keep writing the same game over again. But I found it helpful for understanding the differences in performance and development time. Here are some notes:
6502 Assembly Language on the Atari 800
This was the original version of Dandy. It took several minutes to compile the game. The game was roughly 2000 lines of 6502 assembly source code. (Unfortunately I’ve long since lost the source code.) Since the game data variables all fit in one byte, it was actually pretty easy to write this in assembly. Also the Atari 800 hardware directly supported smooth scrolling of the map, easy generation of sound effects, and 4 joystick ports.
It took me three months of part-time work to write the game. Originally there was a second computer (a Hewlett-Packard Pascal Workstation) that acted as a “dungeon master console”. The idea was that there would be a fifth player that controlled the pace of the game. “Send in the next wave of monsters”, and stuff like that. But this ended up being just a file server, and was eventually replaced with files on the local disk.
Another feature of the original game was that when you left a level its state was stored, so that when you returned to the level everything would be as you left it. But in my play-testing I noticed that the only time people went up was by mistake, so I cut that feature.
C++ and Direct3D 9.0 on Windows XP
This version took about 15 hours to write, and was around 1500 lines of code. It was easy to write and debug. (But after all, I am a full time C++ programmer.)
C# and Managed Direct3D on Windows XP
This version was a port of the C++ version. It took about 5 hours to port, and ended up being around 1100 lines. (It was smaller than C++ due to less boilerplate D3D initialization code.)
F# and Managed Direct3D on Windows XP
This version was a re-write of the C# version, with Direct3D code lifted from the F# interactive 3D sample. It took quite a while (25 hours) to write, partly because I’m new to F# and partly because I was using a borrowed computer (I’m on vacation) that didn’t have Visual Studio installed. So I was stuck using fsi and notepad. Fsi has some benefits for rapid development, but it was tedious to track down errors by copying-and-pasting code between notepad and fsi.
Currently the F# version has more features than the other versions, so it’s not fair to compare the line number count of the current version to the other versions. However, At the point where the F# version had the same functionality as the C# version, the line count was around 900 lines. It was shorter due to a coding style that used shorter variable names, and less white space. This coding style seems to be standard for F#, and is made possible by the type inferencing.
Thoughts on F# for game development
If you do a web search for games written in non-C-derived languages, you’ll see that very few people write two games in a row in a non-C-derived language. I think the reason is that it’s currently still most convenient to write games in a C-derived language. However, to help people who are considering using F# for game development, here’s my thoughts on the benefits and problems:
Benefits of F#
l Functional code makes it easy to factor out common code, making programs shorter
l Being able to omit type names in many places makes programs shorter
l Strong type checking and null-less programming means fewer runtime errors
l Fsi is helpful for use as a “console” during game development. It’s easy to inspect data structures and call code in your game to change game state and test out functions.
l The language support for tagged unions and the match / with language construct are helpful. For example in Dandy there’s a “piece” type that has all the types of data that are present in the game. It’s very handy to use “match” to process piece data in the game.
l Runs roughly as fast as C#.
Problems with F#:
l For loops that execute their terminal value are confusing to C programmers. And the code ends up with lots of for x = 0 to size – 1 statements. It’s too bad that there isn’t a for x = 0 until size syntax.
l Lack of a “break” statement makes loops harder to write. Yeah, I know you’re supposed to factor the loops into helper functions, or use recursive functions but it’s still a pain.
l No language support for enums with assigned integer values, and converting between ints and enums. This feature is very useful in games. You can kludge around it with helper functions, but it’s tedious to write them.
l Ugly array indexing syntax. (I prefer foo[4] to foo.(4) . Fortunately I hear this is being fixed.)
l It’s tedious to have to manually convert between floating point and integers.
l You have to know way too much in order to get code to work. For example, in order to call into the CLR code I needed to know F#, C#, the CLR, how F# marshals code into C#. Compare this to writing the same code in C# where I can just blindly copy-and-paste some example code from the docs.
l No free IDE. The Visual Studio IDE for FSharp is quite good, but it requires a non-free version of Visual Studio. Compare this to C or C# where you can get an excellent free version of Visual Studio.
l Hard to fix syntax errors. Because F# syntax is so different from C-like languages, and because F# lets you omit semicolons, if you accidentally make a syntax error in you source code the resulting error message from the compiler is typically not very helpful. Once you’ve written 20 hours or so of F# code you finally get the hang of the F# syntax, and this becomes less of a problem.
l F# is not currently available on any video game consoles. Whereas C++ will work on all game consoles.
So, having ported a game to F#, I think I see lots of promise in the language. In the future I’d like to try writing a new, 3D game of some sort in F#. I’ll let you know how it goes.