SimulaVR / godot-haskell

Haskell bindings for GdNative
BSD 3-Clause "New" or "Revised" License
171 stars 17 forks source link

godot-haskell

Build Status

Haskell bindings for the Godot game engine.

Getting started with the examples

The easiest way to get started is to have a look at the demos included in the examples directory. First check out "Dodge the Creeps!", your first game from the Godot documentation. Following along with the documentation and the code should make everything understandable.

To build:

git clone --recursive https://github.com/SimulaVR/godot-haskell
stack install godot-haskell:exe:godot-haskell-project-generator
cd godot-haskell/examples/dodge-the-creeps
make

To make changes to the game, in two different terminals:

make stack-watch
make project-watch

The first command will constantly build Haskell code and copy the shared library into the Godot project, demo. The second command will constantly scan the Godot project and build Haskell code out of it.

Load up the game by importing game/project.godot into the editor, which you can do from the commandline with godot game/project.godot. To run the game in the editor press F5, stop it with F8.

Understanding the examples

There are two parts to every project. examples/dodge-the-creeps/game which is the Godot project and examples/dodge-the-creeps/src which are the Haskell sources. When you run cd examples/dodge-the-creeps && make stack to build the demo, it builds the project locally with stack build and then does a cp to copy the resulting shared library into the right place in examples/dodge-the-creeps/game. This way Godot will pick it up. If you just do a stack build without copying, your shared library will never update and Godot will run the old code.

You must regenerate examples/dodge-the-creeps/src/Project any time you modify the Godot project. This directory contains the Godot project mirrored into Haskell, just like @Servant@ provides you with API safety by declaring APIs in Haskell. When you change the name of a node in Godot, this will update a Haskell class instance, which will lead to a type error in your project. You can do this with stack exec godot-haskell-parse-game game src which will watch your project for changes.

Known issues & inconveniences

Setting up your own project.

It's best to start with one of the existing examples, make a copy, and rename the project. If you want to start another project use the stack template template/godot-haskell.hsroots Alternatively, fetch it directly from git:

stack new myproject https://raw.githubusercontent.com/SimulaVR/godot-haskell/master/template/godot-haskell.hsfiles

Changing Godot versions

You will need to regenerate the bindings if you switch Godot versions. At present, these are generated for the version that corresponds to the godot_headers submodule included here. This was 3.1 at the time of writing.

To regenerate bindings:

# Prerequisite
sudo apt-get install jq libcurl4-gnutls-dev # Or equivalent on you OS/Distro
cabal install xml-to-json

# Generate the JSON
xml-to-json godot-install-directory/doc/classes/*.xml | jq -n '[inputs]' &> godot_doc_classes.json
cd classgen
stack build
rm ../src/Godot/Core/* ../src/Godot/Tools/*
stack exec godot-haskell-classgen -- ../godot_headers/api.json ../godot_doc_classes.json ../

That's it! The rest of the bindings are fairly lightweight with few dependencies, so you shouldn't see much breakage in the rest of the package.

If you want to get an idea of what the Haskell libraries are doing, set the environment variable HS_GODOT_DEBUG.

Questions

The primary method of contact is the SimulaVR Discord server. Mirrors are available at Gitter and in the SimulaVR channel at Matrix.

Docs

Most of the API is documented but the lowest-level bindings, like GDNative functions don't have documentation. They are quite intuitive to use though.