Using Clojure we create interesting 3D shapes in Minecraft to the beat of music generated from Overtone.

We achieve this by embedding a Clojure REPL inside a Java Minecraft server which loads Overtone and connects to an external Supercollider instance (What Overtone uses for sound).

Demo

Demo Source code: https://github.com/josephwilk/clj-minecraft/blob/master/src/cljminecraft/overtone.clj

Tools

Java Minecraft server Craftbukkit/Spigot: http://www.spigotmc.org/

Minecraft client (requires purchase) https://minecraft.net

clj-minecraft Bukkit plugin: https://github.com/josephwilk/clj-minecraft

Overtone (patched): https://github.com/josephwilk/overtone/tree/minecraft_overtone

MUD (useful helpers for Overtone): https://github.com/josephwilk/mud

Supercollider: http://supercollider.sourceforge.net

(Dependent on your IDE of choice)

Building the world

We need to install Spigot which is an optimized version of the Craftbukkit Java Minecraft server and install clj-minecraft project as a plugin. Things are complicated by Bukkit no longer being registered in Maven.

Read through the Makefile install:

https://github.com/josephwilk/clj-minecraft/blob/master/Makefile

If your happy clone and run:

1 git clone git@github.com:josephwilk/clj-minecraft.git && make install

Bukkit + clj-minecraft will be installed for you.

Running the world

You will need to edit the minecraft/eula.txt indicating you agree with the license. Then you can run your Minecraft server:

1 java -XX:MaxPermSize=1G -jar spigot-1.8.jar

Seeing the world

Buy and install a Minecraft client: https://minecraft.net

Select >“Multiplayer” >“Direct connect” and enter the “Server Address” as localhost.

Bring music to the world

Install and Boot Supercollider

http://supercollider.github.io

Once installed:

1 2 3 4 5 6 7 #Find the Supercollider binary (scsynth) $ sudo find /. -name "scsynth" /Applications/SuperCollider/SuperCollider.app/Contents/Resources/scsynth #Run Supercollider server /Applications/SuperCollider/SuperCollider.app/Contents/Resources/scsynth -u 57110

Speaking to the Minecraft REPL

clj-minecraft opens a REPL on localhost port 4005. Using emacs and cider connect to this REPL instance.

Boot and connect Overtone:

1 2 3 ( use 'overtone.core ) ( connect-external-server ) # => :happy-hacking

Interaction

Using MUD we have some useful wrappers around Overtone for scheduling functions on beats.

To coordinate graphics and sound we schedule both within a single function.

1 2 3 4 5 6 7 8 9 10 ( require ' [ mud.core :as mud ]) ( defonce highhat-sample ( freesound 53532 )) ( def ride-trigger ( mud/on-beat-trigger 8 ;; Every 8th beat ( fn [] ( highhat-sample ) ;; Play sample ( block 2 10 2 :grass ) ;; Place a block into the Minecraft world )))

Most functions that change the state of the Minecraft world need to be run in the main GUI thread. To achieve this we wrap any state changing function within ui-sync (https://github.com/CmdrDats/clj-minecraft/blob/a3331e925b56becf88d9ef96cab225856e2f7ead/src/cljminecraft/bukkit.clj#L39-L42).

For example a function to place a block into the Minecraft world:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ( import ' [ org.bukkit Location Material ]) ( require ' [ cljminecraft.bukkit :as bk ]) ( require ' [ cljminecraft.items :as i ]) ( def player ( first ( .getOnlinePlayers ( bk/server )))) ( defn block "place a block relative to current players position Example: (block 2 10 2 :grass) " [ x y z material ] ( let [ l ( .getLocation player )) m ( i/get-material material )] ( doto l ( .setX ( + x ( .getX l ))) ( .setY ( + y ( .getY l ))) ( .setZ ( + z ( .getZ l )))) ( bk/ui-sync @ cljminecraft.core/clj-plugin ( fn [] ( doto ( .getBlock l ) ( .setData 0 ) ( .setType ( .getItemType m )) ( .setData ( .getData m )))))))

For further documentation of whats possible, the Bukkit Java docs: https://hub.spigotmc.org/javadocs/bukkit/

clj-minecaft has lots of helpers + examples: https://github.com/CmdrDats/clj-minecraft/tree/master/src/cljminecraft

Fun

Create, play and share all the crazy things you can come up with using Clojure and Minecraft.

For more live programming music and sound checkout my performances as Repl Electric: http://www.repl-electric.com

Credits

Built on the back of lots of great open source projects. Thanks to the Craftbukkit/Spigot contributors, @CmdrDats for clj-minecraft and @samaaron for Overtone and inspiring this crazy journey with the musical Sonic Pi (which supports combining music and Minecraft on the RaspberryPi).