How to Use MineTweaker 3

Prerequisite
Before you can write any MineTweaker scripts, install MineTweaker and create a "/scripts/" directory in the "/minecraft/" directory, if it is not already there. This should be at the same level as the "/mods/" and "/config/" directories. All scripts are written in files with the ".zs" file extension (for example, "witchery.zs"). The name of these files does not matter to the scripts or MineTweaker, however it is recommended to not uses spaces or symbols (excluding underscores) for the sake of convention and ease of access.

ZenScript
Unlike in MineTweaker 2, MineTweaker 3 is built on top of a custom programming language named ZenScript. It allows for more advanced features, such as loops. ZenScript looks much like JavaScript or Java. ZenScript is relatively simple compared to other programming languages, as it is created specifically for MineTweaker.

It is recommended you use the Atom Text Editor, along with the Atom-MineTweaker package rather than a normal text editor, but it is not required.

Alternative packages exist for other editors, including Notepad++, Visual Studio Code, and Sublime.

Functions
In ZenScript, a function is a procedure that does something, like add or remove a recipe. The most basic function in the print function, as shown below.

print("Hello, FTB Wiki!");

The print function will log a message into the minetweaker.log file in your minecraft directory. That file may contain other messages, but this should be found somewhere within it.

Notice the called function has a semicolon at the end of it. A semicolon is required after the end of each statement.

INFO: Hello, FTB Wiki!

Most functions in MineTweaker relate to the addition and removal of recipes. It's important to know the unlocalized name of the item and blocks you want to use, as well as the mod ID that adds that particular item or block. Various tools exist to discover these, including NEI's data dumping feature.

To remove a crafting recipe, a simple "remove" function exists:

recipes.remove();

When Minecraft is launched, you will find you can no longer craft Sticks. In this example, minecraft is treated as the mod ID, and stick is the unlocalized name of the Stick.

Other examples:

This will remove the crafting recipe for the Bed: recipes.remove(); And this will remove the crafting recipe for the Blaze Rail from Natura: recipes.remove(); Natura is the mod ID of Natura, and Blazerail is the unlocalized name of the Blaze Rail.

Remember: you can call multiple functions in one script, like shown below.

print("Script starting!"); recipes.remove(); recipes.remove(); print("Script ending!");

Spaces and new lines don't mean anything in ZenScript, meaning you can do some funky things.

print("Script starting!"); recipes.remove(); recipes.remove();

print("Script ending!");

Of course, for the sake of readability, it is recommend that each statement gets its own line.

Calling a function with multiple parameters and adding shaped recipes
In ZenScript, an argument is the value you provide to a parameter in a function.

recipes.remove(); In the example above, the Stick is the argument, and IItemStack Output is the parameter.

Often, a function needs more than one argument. For example, adding a new recipe requires two; one for the output, and one for the recipe itself. recipes.addShaped(, , , ], [null, , null],  [null, , null);

As you can likely guess, the above script adds the Diamond Pickaxe recipe.

Take some time to reevaluate the script: recipes.addShaped(, , <minecraft:diamond>, <minecraft:diamond>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null);


 * Notice the word null. In this case, null means nothing is required in that slot.
 * Notice the square brackets ([ and ]). For each right square bracket, there's a left bracket. The entire recipe is in a set of square brackets, and each line is in another set of square brackets.
 * Also notice the semicolon. Remember, each statement ends with a semicolon.

Here's another example: recipes.addShaped(<minecraft:stone_pickaxe>, <minecraft:stone>, <minecraft:stone>, <minecraft:stone>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null);

Which produces:

Of course, that last example does not replace the Stone Pickaxe recipe; it just adds a new recipe for it. If you wanted to replace it, you'd have have to remove the recipe, and then add it again. recipes.remove(<minecraft:stone_pickaxe>);

recipes.addShaped(<minecraft:stone_pickaxe>, <minecraft:stone>, <minecraft:stone>, <minecraft:stone>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null);

Variables and Values
In ZenScript, a Value is an item (or other type) that can be set and used later. That might sound complicated, but it's actually quite simple. The val keyword is used for declaring a value. For example, val stonePick = <minecraft:stone_pickaxe>; declares a value named "stonePick" with the value of "<minecraft:stone_pickaxe>". Values are especially useful so you can type less and still get the same effect. For example, recipes.remove(<minecraft:stone_pickaxe>);

recipes.addShaped(<minecraft:stone_pickaxe>, <minecraft:stone>, <minecraft:stone>, <minecraft:stone>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null); can be simplified to: val stonePick = <minecraft:stone_pickaxe>; val stone = <minecraft:stone>; val stick = <minecraft:stick>;

recipes.remove(stonePick);

recipes.addShaped(stonePick, stone, stone, stone], [null, stick, null],  [null, stick, null); It might not look like a big difference, but it really is if you use the value a lot. Do note using values are mostly optional, but they're considered a good coding practice for ZenScript and other similar programming languages.

A Variable is just like a value, but it can be set multiple times. For example, var block = <minecraft:glass>;

recipes.remove(block);

block = <minecraft:lapis_block>;

recipes.remove(block); will remove both the Glass block and the Lapis Block. If you replace "var" with "val", some sort of error will occur, and the script will likely not work.

The variable feature might not look very useful right now, but it's vital in more advanced scripts.

Comments
In ZenScript, a Comment is a structure in code that is ignored by the interpreter, but is created for readability.

That sounds kind of confusing, but it's really not complicated at all. A single-lined comment in ZenScript can be started with "#" or "//"

// Anything past the "//" here is ignored and doesn't do anything. Same with below.

recipes.addShaped(stonePick, <minecraft:stone>, <minecraft:stone>, <minecraft:stone>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null);
 * 1) Makes the stone pick be craftable with stone

A multi-lined comment is started with "/*" and ended with "*/".

/* Everything between the symbols is ignored. Note that there are no nested comments; a multi-lined comment cannot be in another multi-lined comment. recipes.addShaped(stonePick, <minecraft:stone>, <minecraft:stone>, <minecraft:stone>], [null, <minecraft:stick>, null],  [null, <minecraft:stick>, null);

Comments are used for a variety of reasons; for explaining confusing code, explaining what a function does, listing copyright information, and to disable code without deleting it.

It's considered good practice to include comments documenting at least every section of your code, so that it can be read and understood by someone else who is unfamiliar with your intent - including you, when you need to make changes later.

More information
For more detailed information, please consult the MineTweaker 3 wiki.