Skip to content

damn/gdl

Repository files navigation

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

(ns gdl.hello-world
(:require [gdl.backends.libgdx.app :as app]
[gdl.context :refer [render-gui-view draw-text]]
[gdl.screen :refer [Screen]]))
(defn draw [context]
(draw-text context {:text "Hello World!" :x 400, :y 300}))
(defrecord MyScreen []
Screen
(show [_ _context])
(hide [_ _context])
(render [_ context]
(render-gui-view context draw)))
(defn create-context [default-context]
(assoc default-context ::my-screen (->MyScreen)))
(defn -main []
(app/start {:app {:title "Hello World"
:width 800
:height 600
:full-screen? false}
:create-context create-context
:first-screen ::my-screen}))

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

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published