BGM - The Block Generator for Minecraft

v0.0.2 Runs on Windows, Linux

This information is for version 0.0.2.
Both the full version and a demo of BGM are available on itch.io.

Early version

Please note that this is a very early version of BGM. The syntax, functions and general functionality will likely change in the future.
Avoid creating a large database of scripts for now, since they might not work with future versions.

Demo Version

Note that the demo works just like the full version and all documentation is valid for it as well.
The only difference is that the executable is called bgmDemo instead of bgm and that there’s a limit for the maximum number of generated blocks.
The demo will simply reject generating output if this limit is exceeded.

Memory Usage

Be careful when defining huge structures since these can cause the creation of a lot of blocks, possibly filling your entire memory.
You must therefore be careful when running scripts from others.

Language

BGM uses its own language to describe the generation of blocks.

Syntax

// Single line comment

/* Multi
   line
   comment
*/

for i in 0..10 {
  movedBy [i 0 30] {
    hollowed {
      sphere 30
    }
  }
}

General

Expressions are used to generate blocks.
The final result is the union of the results of all expressions.
There’s expressions that use scopes via { and }. These expressions apply to everything within the scope and can be nested.

Simple Example

Please note the detailed description of the expressions below.

sphere 5

movedBy [30 0 0] {
    sphere 7
}

material "birch_log" {
  movedBy [60 0 0] {
      sphere 10
  }
}

Expressions

Definition of positions / shifts

Square brackets with 3 integer values or variable names defining x, y and z.

// [XVALUE YVALUE ZVALUE]
[1 2 i]

Placing a single block at the defined position

put keyword followed by the position

// put POSITION
put [0 0 2]
put [1 2 3]
put [1 2 4]
put [1 2 5]

Definition of general direction

x, y or z define the general orientation / direction of some expressions.

// x or y or z
flipped x {}
flipped y {}
flipped z {}

Basic shapes

There’s several basic shapes that you can use within your scripts.

// sphere RADIUS
sphere 5

// cube SIZE
movedBy [15 0 0] {
    cube 5
}

// box SIZE_X SIZE_Y SIZE_Z
movedBy [30 0 0] {
    box 5 7 9
}

// disc DIRECTION RADIUS
movedBy [45 0 0] {
    disc y 6
}

// cylinder DIRECTION RADIUS HEIGHT
movedBy [60 0 0] {
    cylinder y 6 30
}

Moving blocks relatively

You can move blocks relatively by wrapping them with a movedBy followed by a position.
The shift applies to everything within the { scope }.

// movedBy POSITION {}
movedBy [1 2 12] {
    sphere 30
}

Moving blocks absolutely

You can move blocks absolutely by wrapping them with a movedTo followed by a position.
The blocks within the { scope } are moved to the given position in such a way, that their center is located there.

// movedTo POSITION {}
movedTo [0 10 0] {
  sphere 3
}

Copying blocks relatively

You can copy blocks relatively by wrapping them with a copiedBy followed by a position.
The shift applies to a copy of everything within the { scope }.

// copiedBy POSITION {}
copiedBy [5 0 0] {
  sphere 3
}

Copying blocks absolutely

You can copy blocks absolutely by wrapping them with a copiedTo followed by a position.
The blocks within the { scope } are copied to the given position in such a way, that their center is located there.

// copiedTo POSITION {}
copiedTo [5 0 0] {
  sphere 3
}

Setting the material

You can set the material of blocks via the material keyword.
The material applies to everything within the { scope } unless overwritten further in.
The default material is cobblestone.

// material "NAME" {}
material "cobblestone" {
    sphere 30
}
movedBy [10 0 0] {
    material "birch_wood" {
        sphere 30
    }
}

Filtering by material

You can use only followed by a material to only keep blocks of this material within the { scope }.

// only "NAME" {}
only "cobblestone" {
  movedBy [10 0 0] {
    material "birch_log" {
      sphere 2
    }
  }
  material "cobblestone" {
    sphere 3
  }
}

Conditions

You can use if followed by a condition to only generate the blocks if true.
Please note that there’s currently only the equality check via ==.

// if CONDITION {}
if i == 3 {
    ...
}

Loops

You can use loops to generate blocks multiple times.
You can use the iteration variable within the scope.

// for NAME in START..END {}
for i in 1..10 {
    movedBy [i 0 0] {
        cylinder y 3 i
    }
}

Difference

You can generate the difference of the first minus the second scope.

// difference {} {}
difference {
    sphere 30
} {
    movedBy [15 0 0] {
        sphere 20
    }
}

Intersection

You can generate the intersection of two scopes.

// intersection {} {}
intersection {
    sphere 20
} {
    movedBy [15 0 0] {
        sphere 20
    }
}

Extrusion

You can extrude an expression by defining the motion/shift of the extrusion and what to be extruded via a scope.

// extruded POSITION {}
extruded [30 30 30] {
    sphere 10
}

Hollowing

You can remove every internal block from an expression by using hollowed.
Note that the result will look the same as before until you poke holes into it.
This is handy to reduce the total number of blocks.

hollowed {
    sphere 30
}

Mirroring

You can mirror a scope via the mirrored keyword and a direction.
Note that you’ll usually want to apply a movedBy within the instruction, since most shapes are symmetrical.

mirrored x {
    movedBy [30 0 0] {
        sphere 30
    }
}

Flipping

You can flip a scope via the flipped keyword and a direction.
Note that you’ll usually want to apply a movedBy within the instruction, since most shapes are symmetrical.

flipped x {
    movedBy [10 0 0] {
        sphere 30
    }
}

Surround

surrounded will place blocks of the given material around the scope.

sphere 20
movedBy [15 0 0] {
    surrounded "birch_wood" {
        sphere 20
    }
}

Replaced

replaced will replace every block of the first material with the second material within the scope.

replaced "cobblestone" "water" {
  material "birch_log" {
    sphere 2
  }
  movedBy [5 0 0] {
    material "cobblestone" {
      sphere 3
    }
  }
}

Removal of blocks

removed will remove any block with the given material within the scope.

removed "cobblestone" {
  movedBy [2 0 0] {
    material "cobblestone" {
      sphere 3
    }
  }
  material "birch_log" {
    sphere 3
  }
}

Functions

You can define functions via the fn keyword followed by the wanted name and required parameters.
Please note that function definitions must appear at the top level of your program.

// fn NAME_FUNCTION(PARAM1 PARAM2 PARAMN) {
//   CODE_OF_FUNCTION    
//}

fn movedSphere(r x y z) {
    movedBy [x y z] {
        sphere r
    }
}

You can then call functions via the call keyword anywhere in your program.

// call NAME_FUNCTION(PARAM1 PARAM2 PARAMN)
call movedSphere(12 22 23 24)

Preparation

In order to use BGM you have to create a datapack for your save. (See https://minecraft.gamepedia.com/Data_pack for additional information)
Within your Minecraft home folder (e.g. .minecraft) you’ll find the saves folder with a folder for your world. In there you’ll find a datapacks folder. For example ./minecraft/saves/WORLD_NAME/datapacks
I’ll use bgm as folder name and run as function name, but you can choose whatever you want.
Create the following folders and files within datapacks:

./bgm/pack.mcmeta
./bgm/data/bgm/functions/run.mcfunction

Content of pack.mcmeta (The content doesn’t really matter, it just has to be valid)

{
   "pack": {
      "pack_format": 3,
      "description": "Doesnt matter"
   }
}

run.mcfunction shall contain the output of bgm.
The final folder structure will then look similar to:

MINECRAFT_HOME_FOLDER/
  saves/
    WORLD_NAME/  
      datapacks/
        bgm/
          pack.mcmeta
          data/
            bgm/
              functions/
                run.mcfunction

Using / Running BGM

Make sure you’re either in the folder where you placed bgm.exe or have it added to your PATH.
You can run it by passing the path of the program as first parameter.
(If you only have the demo, replace bgm with bgmDemo below)

// Windows
bgm.exe program.txt

// Linux
bgm program.txt

It will print the result to console. You can write the result to a file via

// Windows
bgm.exe program.txt > run.mcfunction

// Linux
bgm program.txt > run.mcfunction

If you set everything up as in the Preparation folder, you can directly write to the final path, saving you some time

... > MINECRAFT_HOME_FOLDER/saves/WORLD_NAME/datapacks/bgm/data/bgm/functions/run.mcfunction

Parameters

There’s several parameters you can pass to bgm.
Note that the path to the program must always be the first parameter.

bmg.exe program.txt --help

–help or -h

Print a help text basically showing the information here

–delete or -d

Create a deleting output by always placing air blocks instead of the defined materials within the program

–relative or -r

Consider all positions relative to the current player position (otherwise absolute world positions)

–mode or -m

Used replacement mode when placing blocks. [replace | destroy | keep]

  • replace: overwrite blocks, drop nothing
  • destroy: overwrite blocks and drop them
  • keep: don’t overwrite blocks and only place new blocks on air

–shiftx or -x

Final x-shift applied to all positions

–shifty or -y

Final y-shift applied to all positions

–shiftz or -z

Final z-shift applied to all positions

Example with many parameters

bgm.exe program.txt --shiftx 40 --shifty 30 --relative --delete > output.txt

Usage in Minecraft

Please make sure cheats are enabled for your world, otherwise below won’t work.

Once you prepared your files and folders and filled run.mcfunction with the commands, you can head over to Minecraft to run the commands. (See https://minecraft.gamepedia.com/Commands for additional information)

You can run commands by pressing t or / on your keyboard.

Call /reload whenever you made changes to run.mcfunction.
Call /function bgm:run to execute the commands.

Please note that there’s a rather low default limit on the maximum allowed number of commands. You can increase this limit by calling /gamerule maxCommandChainLength NUMBER, so e.g. /gamerule maxCommandChainLength 1000000.
Please note that executing such large scripts might take some time and cause Minecraft to hang.

Changelog

0.0.2

  • Rename moved to movedBy [find and replace moved -> movedBy to fix your scripts]
  • Add replaced
  • Add movedTo
  • Add removed
  • Add copiedBy and copiedTo
  • Add only
  • Fix issue in extruded where rounding errors could cause minor extrusion movements to not occur at all
  • Increase the maximum commands in the demo version from 50,000 to 100,000