# Minecraft functions in Perl

So Jeff said he wanted a haunted castle put in the North West corner of the Hallowe’en world we were building in Minecraft. If you missed the Minecraft 11th birthday world, there are still bits of it visible at mc.livingcomputers.org as of June 4, 2020.

Ok, a castle… Hmm, how about a 4 level castle about 40 blocks in diameter? A basement, three floors, and a roof? I see builds with circles in Minecraft, how do I do that? I couldn’t seem to convince a Minecraft function to do much math. Perl can do math, how about I write a Perl script to do the calculations? I started with something like this:

`my \$x_offset = -80;my \$y_offset = 58;my \$z_offset = -81;my \$radius = 25;my \$last_x = 0;my \$last_z = 0;for (my \$z = -1 * \$radius; \$z < \$radius; \$z += 1) { my \$blockx = int(\$radius * cos(asin((\$z + 0.5) / \$radius))); my \$blockz = int(\$z) + 1; printf "fill %d %d %d %d %d %d stone_bricks\n", \$x_offset - \$blockx, \$y_offset, \$z_offset + \$blockz, \$x_offset - \$last_x, \$y_offset + 15, \$z_offset + \$blockz; printf "fill %d %d %d %d %d %d stone_bricks\n", \$x_offset + \$last_x, \$y_offset, \$z_offset + \$blockz, \$x_offset + \$blockx, \$y_offset + 15, \$z_offset + \$blockz; \$last_x = \$blockx; \$last_z = \$blockz}`

OK, now I had a stone brick cylinder 40 blocks in diameter, and 15 blocks high. Then I added a bridge across the moat:

`printf "fill -78 73 -49 -82 73 -60 stone_bricks\n";printf "fill -82 73 -48 -78 73 -48 stone_brick_stairs\n";printf "fill -78 74 -49 -78 74 -60 stone_brick_wall\n";printf "fill -82 74 -49 -82 74 -60 stone_brick_wall\n";printf "fill -78 75 -60 -78 77 -60 stone_brick_wall\n";printf "fill -82 75 -60 -82 77 -60 stone_brick_wall\n";printf "fill -78 78 -60 -82 78 -60 stone_brick_wall\n";printf "setblock -82 75 -49 jack_o_lantern[facing=south]\n";printf "setblock -78 75 -49 jack_o_lantern[facing=south]\n";printf "setblock -82 75 -59 jack_o_lantern[facing=south]\n";printf "setblock -78 75 -59 jack_o_lantern[facing=south]\n";printf "fill -79 74 -61 -81 77 -61 air\n";printf "fill -79 77 -61 -81 77 -61 iron_bars\n";`

Then I added a bunch of maze stuff. I got complaints that it was too dark, but it was supposed to be dark and spooky! Later on, I added the lava moat. Other interesting bits showed up like:

`printf "setblock -74 70 -72 stone_pressure_plate\n";printf q!setblock -74 69 -71 command_block{Command:"give @a[x=-74,y=70,z=-72,dy=2] gold_block",TrackOutput:0}!;printf "\n";`

`printf "setblock -93 72 -70 stone_button[facing=east]\n";printf "setblock -93 71 -70 dropper[facing=east]\n";printf q!data merge block -93 71 -70 {Items:[{Slot:1b,id:"diamond_block",Count:64b}]}!;printf "\n";`

Here we had to use a different version of a quoted string in Perl, in order to include the quote marks in the Minecraft command. Sorry, the lines are wrapping.

This was where I wanted to give the player something.

That is all fairly straight forward, but sometimes you only want some, but you don’t want to do them all by hand, so:

`foreach (-72, -75, -78, -82, -85, -88){printf "setblock -82 81 %d wall_torch[facing=west]\n", \$_;}`

or:

`foreach (-70, -71, -73, -74, -76, -77, -83, -84, -86, -87, -89, -90){printf "setblock -82 81 %d minecraft:red_wall_banner[facing=west]\n", \$_;}`

When your player ends up down in a deep ravine, you might have to do something like:

`printf q!setblock -16 17 -44 oak_wall_sign[facing=west]{Text1:"\"Follow\"",Text2:"\"the\"",Text3:"\"Torches\""}!;printf "\n";`

Why would I go through all this trouble? When we run a public Minecraft server, we sometimes take a lot of grief. With a Minecraft function, an OP can just type: `/function minecraft:castle.mcfunction` and Poof, whatever has happened has gone away, without shutting down the server, or kicking players off!

Happy Mining!