Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

World generation

CmdrDats edited this page · 3 revisions

World Generation

(:require [cljminecraft.blocks :as bl])

Source: blocks.clj

Bukkit Docs:


The world generation API of cljminecraft tries to make defining structures, landscapes and world manipulation more declarative and takes a similar approach to that of something reminiscent of Logo:

;; Draw a hollow box from the first online player's location
(def ctx (setup-context (first (.getOnlinePlayers (bk/server)))))
  (extrude :up 5
    (forward 8) (right 8) (back 8) (left 8)))


First, you need to setup a context to provide run-actions with a starting point and state - see the setup-context function as an example of such a context. This is a helper function to setup a context from a given player's name.

Then, you simply use run-actions, providing the context and an arbitrary list of actions. The actions can themselves be composed of sub-lists of actions to make composing actions straightforward, eg:

(defn box []
  [(forward 8) (right 8) (back 8) (left 8)])

(run-actions ctx (extend :up 5 (box)))

To generate structures especially from a different thread from the main UI thread, I recommend using bk/ui-sync, see Bukkit Utilities

(bk/ui-sync plugin #(run-actions ctx ...))



Possible actions include forward, back, left, right, up, down. Each supports a distance to move.


When turning, you are adjusting the relative direction of further actions so that:

(run-actions ctx (forward 8) (turn-left) (forward 8))

has almost the same effect as just (forward 8) (left 8). This lets you define structures purely in relative space which means that rotating it involves a simple turn-left, turn-right or turn-around before executing it.


There are pen-up, pen-down and pen-toggle commands that let you move without painting any blocks along the way.

There is also a material function that lets you set the current material your pen should be painting :

(run-actions ctx (material :stone) (forward 2) (material [:wood :jungle]) (up 2))


A mark is a little bit like a clipboard - it can store stuff like the current location, relative angle and copied blocks.

Use mark to create a mark, jump to put the pointer back to that mark..

You can use the function gen-mark to create yourself a unique marker name to refer to in your functions. This is recommended so that you don't clash within a context:

(let [m (gen-mark)]
  (run-actions ctx (mark m) (forward 10) (left 8) (jump m)))

There are other functions that work with marks, like copy, cut, paste, copy-to-mark, cut-to-mark, clear-mark, line-to-mark - play around with them and get a feel for how they work


extrude lets you quickly repeat a set of actions in a given direction a certain number of times. See the example near the top


If you want to run a set of actions, but not affect your current point - simply call fork with those actions.

(run-actions ctx 
  (fork (forward 8)) 
  (fork (left 10) (up 5)) 
  (fork (down 5) (left 3)))
Something went wrong with that request. Please try again.