DEV Community

Cover image for OpenGL Game in Clojure CLR (Mono/.Net) - Part1 (The Setup)
Pankaj Doharey
Pankaj Doharey

Posted on • Edited on

3

OpenGL Game in Clojure CLR (Mono/.Net) - Part1 (The Setup)

Introduction

I gave been thinking about writing 2D/3D OpenGL games in clojure for sometime. When it comes to developing games you have many choices with clojure. You can develop games for webgl using clojurescript + Webgl/Canvas Api or any 2D/3D javascript library of your choice. You can also use JVM and its many OpenGL libraries like LWJGL.

There is a third choice if you want your games to be highly portable you can choose a game engine with C# bindings. Or better yet use Clojure-CLR to develop on the .Net framework. This is a first tutorial in hopefully a series of tutorials targeting the third option.

Since C# on .Net is the most popular choice of game development for a large number of Indie and Small studios i think it would be an excellent choice to use Clojure CLR to develop cross platform games on the Mono/.Net Framework.

The tutorial is geared towards development on a macOS with mono/.Net but the it should be directly applicable on Ubuntu/Linux or Windows.

Setup.

In order to start developing Clojure CLR application on a mac we need to install Mono which is an open-source implementation on Microsoft .Net Framework on Linux and Mac.

The simplest way to install mono on a mac is using the mac universal package from here https://www.mono-project.com/download/stable/

This will also install nuget, which is a package manager to fetch .Net packages.

Once Mono is installed, which you can check by typing the following on the terminal.

$ mono --version
=> Mono JIT compiler version 6.0.0.313 (tarball Fri Jul 19 16:02:10 BST 2019)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com

Install Clojure-CLR

Now let's install clojure-clr, though you are free to try official Clojure-CLR this tutorial uses a particular fork of Clojure-CLR maintained by Ramsey Nasser and co of Arcadia Technologies, since that is the Clojure-CLR i found most success with instead of the official binaries.

$ git clone git@github.com:arcadia-unity/clojure-clr.git
$ cd clojure-clr/
$ git checkout unity
$ make

If the compilation is successful this should produce a Release directory in bin/4.0/Release/. Now you should add this directory as an entry to CLOJURE_LOAD_PATH environment variable in ~/.bash_profile so that we can write build scripts to find and use clojure-clr binaries.

export CLOJURE_LOAD_PATH=$HOME/Projects/clojure-clr/bin/4.0/Release/

It would also be useful to add the following aliases to ~/.bash_profile
#Clojure clr repl.
alias cljclr="mono $CLOJURE_LOAD_PATH/Clojure.Main.exe"
#Clojure clr compiler.
alias cljcomp="mono $CLOJURE_LOAD_PATH/Clojure.Compile.exe"

Also do remember to source the bash profile: $ source ~/.bash_profile.

The above aliases are clojure-clr repl and compiler respectively.

Invoking $ cljclr on the terminal and you would be greeted with a clojure repl.

Clojure 1.10.0-master-SNAPSHOT
user=>

You can run clojure commands on the repl now.

user => (+ 1 2 3)
6
you can press Ctrl+c to exit the repl.

The last thing we need to install is a C# bindings for OpenGL, one such wrapper in OpenTK.

we will begin by creating a directory structure for our app.

$ mkdir -p ~/Projects/cljopentk/extern
$ mkdir -p ~/Projects/cljopentk/build
$ cd ~/Projects/cljopentk/extern
nuget install OpenTK -ExcludeVersion

this should download the latest OpenTK bindings into the extern directory. An ls into the directory should show the following dlls.

$ ls extern/OpenTK/lib/net20/
>> OpenTK.dll OpenTK.pdb OpenTK.xml

now lets create a core.clj file in the parent directory cljopentk.

$ cd ..
$ touch core.clj build.sh

Build Script.

Make the build.sh as executable,

$ chmod +x build.sh

and paste the following code in it.

#!/usr/local/bin/bash
runtime="mono"
cljcomp=$CLOJURE_LOAD_PATH/Clojure.Compile.exe
compile(){
CLOJURE_COMPILE_PATH=build/ $runtime $cljcomp core
}
link_dlls(){
ln -s $CLOJURE_LOAD_PATH/*.dll build/
cd build/
ln -s ../extern/OpenTK/lib/net20/OpenTK.dll .
}
run(){
$runtime build/*.exe
}
release(){
rm -rf release
mkdir release
cp $CLOJURE_LOAD_PATH/*.dll release/
cp build/*.exe release/
echo "A build cretaed in release directory"
}
case "$1" in
c|compile)
compile
;;
l|link)
link_dlls
;;
r|run)
run
;;
z|rel)
release
;;
*)
echo "Clojure CLR build script."
echo "Usage: $0 [Options]"
echo "Mandatory Options :
c | compile
l | link
r | run
z | rel"
esac
view raw build.sh hosted with ❤ by GitHub

Create DLL softlinks for program execution.

$ ./build.sh link

Hi World!

Now let us write a small clojure "hi-world" program.
Paste the following code in the newly created core.clj.

(ns core
(:gen-class))
(import [System])
(defn -main[]
(System.Console/WriteLine "Hi World"))
view raw core.clj hosted with ❤ by GitHub

Compile the program using the build script.

$ ./build.sh c

Run the program with.

$ ./build.sh r
Hi World

Now that we have a basic setup to compile clojure-clr programs we can continue with developing the OpenTK/OpenGL game.

Since you are still reading perhaps you want to checkout the next post in this series :

All Posts:

Part 2 - The Game Window
Part 3 - Handling Input

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more