(:require [cljminecraft.blocks :as bl])
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))))) (run-actions ctx (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
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-around before executing it.
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.
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
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)))