damn / gdl

Functional 2D game engine in clojure

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What is GDL?

The vision of GDL is to be a Game Development Language and make it utterly simple to write games!

GDL is a functional 2D game engine built around the idea of a context object which holds the current state of the application.

As you can see in the hello-world example below we call create-context once on app start and then it gets passed every frame to the render function.

The context object is is a clojure record (gdl.context.Context) which implements certain protocols, as defined in gdl.context.

The current context is stored in an atom in gdl.app/current-context. It is not suggested to access the state other than for debugging. It is only used by UI callbacks, for changing the screen and passed to the application render.

GDL is basically a clojure API over the 2D parts of of libgdx, as GDL evolved as an engine for Cyber Dungeon Quest, an action RPG project. But you can easily extend the API for more libgdx features.

You have full access to all libgdx under the hood and can do direct java interop anytime or acccess the OpenGL context, etc.

Libgdx supports android and ios too, but I have not used those backends yet.

The following things can be all called on the context object.

  • 📺 Change screens (different separate applications 'screens' like main-menu, options-menu, etc )
  • 🌎 Having a GUI-view and a World-view (with a world-unit-scale, which means you can draw and reason about your game world at world-coordinates and not pixel-coordinates)
  • 🎆Load and draw images
  • 📐Drawing geometric shapes
  • 🔈Playing sounds
  • 🎮Checking for Mouse/Key input
  • ☑️Scene graph for UI widgets using vis-ui
  • 🔤Loading truetype fonts & drawing text
  • 🗺️Loading tiled .tmx maps and drawing them with lights&shadows in world-unit-scale
  • 🖱️ Loading/setting cursors

Hello World

You can run the hello world example in this repository with:

lein run -m gdl.hello-world

https://github.com/damn/gdl/blob/f34a451e559363a1876e9d386516108333bdc5ce/test/gdl/hello_world.clj#L1-L25

On Mac

You need to set this environment variable:

export JVM_OPTS=-XstartOnFirstThread

Updating the context

At the moment render does not return a new context object, as I am using atoms for my entities and state in the RPG project. This proved to be quite useful and I am not sure it is possible to remove those atoms as they are used as references and save the lookup by entity :id.

TODO: Still it might be useful for smaller projects to be able to just return a new context at the end of render.

Extending the Context for your game

In Cyber Dungeon Quest I have defined more game-specific context protocols.

There is an example in context.mouseover-entity how to extend the context with your own protocols.

Basically you call extend-type gdl.context.Context with your protocols and merge the necessary context-data at app start with the existing default-context.

By using namespaced keywords like :context/mouseover-entity and clojure's map destructuring it becomes quite simple&easy to manage all the data in one object.

Installation

Add the following to your project.clj file:

:repositories [["jitpack" "https://jitpack.io"]]

:dependencies [[com.github.damn/gdl "main-SNAPSHOT"]]

Note: the jitpack for main-SNAPSHOT seems not to be working at the moment, use the latest commit hash!

Games made with GDL

About

Functional 2D game engine in clojure


Languages

Language:Clojure 79.3%Language:Java 20.7%