## Introduction

A Clojure library that provides a wrapper for [libGDX](http://libgdx.badlogicgames.com/), allowing you to write 2D and 3D games that run on desktop OSes (Windows, OS X, and Linux) and mobile OSes (Android and iOS) with the same Clojure codebase.

## Getting Started

There are several different ways to create a project:

* [Leiningen](https://github.com/technomancy/leiningen): `lein new play-clj hello-world`
* [Nightcode](https://nightcode.info/): Click "New Project", provide a name, and choose the "Game" option
* [Nightmod](https://nightmod.net/): Easiest option for beginners

## Justification

The best thing about making a game in Clojure is that you can modify it in a REPL while it's running. By simply reloading a namespace, your code will be injected into the game, uninhibited by the restrictions posed by tools like HotSwap. Additionally, a REPL lets you read and modify the _state_ of your game at runtime, so you can quickly experiment and diagnose problems.

Clojure also brings the benefits of functional programming. This is becoming a big topic of discussion in gamedev circles, including by [John Carmack](http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/). Part of this is due to the prevalence of multi-core hardware, making concurrency more important. Additionally, there is a general difficulty of maintaining object-oriented game codebases as they grow, due to complicated class hierarchies and state mutations.

## Documentation

* Check out [the example games](https://github.com/oakes/play-clj-examples)
* Read [the tutorial](TUTORIAL.md)
* Read [the generated docs](http://oakes.github.io/play-clj)
* Join the discussion on [/r/playclj](http://www.reddit.com/r/playclj/)
* Look at this commented example:

```clojure
(ns game-test.core
  (:require [play-clj.core :refer :all]
            [play-clj.g2d :refer :all]))

; define a screen, where all the action takes place
(defscreen main-screen
  ; all the screen functions get a map called "screen" containing various
  ; important values, and a vector called "entities" for storing game objects
  
  ; the entities vector is immutable, so in order to update it you must simply
  ; return a new vector at the end of each screen function
  
  ; this function runs only once, when the screen is first shown
  :on-show
  (fn [screen entities]
    ; update the screen map to hold a tiled map renderer and a camera
    (update! screen
             :renderer (orthogonal-tiled-map "level1.tmx" (/ 1 8))
             :camera (orthographic))
    (let [; load a sprite sheet from your resources dir
          sheet (texture "tiles.png")
          ; split the sheet into 16x16 tiles
          ; (the texture! macro lets you call TextureRegion methods directly)
          tiles (texture! sheet :split 16 16)
          ; get the tile at row 6, col 0
          player-image (texture (aget tiles 6 0))
          ; add position and size to the player-image map so it can be drawn
          player-image (assoc player-image :x 0 :y 0 :width 2 :height 2)]
      ; return a new entities vector with player-image inside of it
      [player-image]))
  
  ; this function runs every time a frame must be drawn (about 60 times per sec)
  :on-render
  (fn [screen entities]
    ; make the screen completely black
    (clear!)
    ; render the tiled map, draw the entities and return them
    (render! screen entities))
  
  ; this function runs when the screen dimensions change
  :on-resize
  (fn [screen entities]
    ; make the camera 20 tiles high, while maintaining the aspect ratio
    (height! screen 20)
    ; you can return nil if you didn't change any entities
    nil))

; define the game itself, and immediately hand off to the screen
(defgame game-test
  :on-create
  (fn [this]
    (set-screen! this main-screen)))
```

## Licensing

All files that originate from this project are dedicated to the public domain. I would love pull requests, and will assume that they are also dedicated to the public domain.
