Differences to other languages
This page will highlight the differences of Shulkerscript and vanilla mcfunction and mcscript.
Functions
The first difference you can see is that Shulkerscript takes a much different approach to functions than mcfunction and mcscript. The following example declares two functions and calls them second from the first one.
#[load]fn first() { second();}
fn second() { /say Hello, world!}
function functions:second
say Hello, world!
#file: first/function functions:second
#file: second/say Hello, world!
or alternatively
#file: firstrun function second { /say Hello, world!}
Comments
Comments can be expressed differently in all three languages. Shulkerscript uses //
for single-line comments and /* */
for multi-line comments.
// this is a commentfn hello() { /// this comment will be included in the compiled output /* this is a multi-line comment */ /say Hello, world!}
# this is a comment# multiline comments have to be done manuallysay Hello, world!
// this is a regular comment# this comment will be included in the compiled output/* this is a multi-line comment*//say Hello, world!
Execute Command
Both Shulkerscript and mcfunction offer an easier way for using execute commands, as they are common when building datapacks.
fn execute() { as("@a"), at("@s") { /setblock ~ ~-1 ~ minecraft:stone }}
execute as @a at @s run setblock ~ ~-1 ~ minecraft:stone
as(@a), at(@s) { /setblock ~ ~-1 ~ minecraft:stone}
If-Else Statements
Shulkerscript and mcscript offer a more convenient way to write if-else statements.
fn conditional() { if("entity @p[distance=..5]") { /say You are close! } else { /say You are far away! }}
execute if entity @p[distance=..5] run say You are close!execute unless entity @p[distance=..5] run say You are far away!
if('entity @p[distance=..5]') { /say You are close!} else { /say You are far away!}
Logical operators
Both in Shulkerscript and mcscript, logical operators can be used to combine multiple conditions.
In the following code examples, the conditions are represented by A
, B
, etc. as placeholders for real conditions.
fn logical() { if("A" && "B" || "C") { /say A and B or C }}
The AND operator takes precedence over the OR operator, so the above code is equivalent to A && (B || C)
.
The code is compiled in such a way, that regardless in which way the expression is true, the command will only run once.
execute if A if B run say A and B or Cexecute if C run say A and B or C
if(('A' && 'B') || 'C') { /say A and B or C}
Interfering with conditions
The difference between Shulkerscript and the other two languages is that Shulkerscript compiles to a version where it is not possible to trigger both the if and the else statement at the same time. This could be possible when using the trivial approach to translate the following to mcfunction:
fn thisWorks() { if("block ~ ~-1 ~ minecraft:stone") { /setblock ~ ~-1 ~ minecraft:cobblestone } else { /say Not on stone }}
Here the second command will always be executed, because if the condition is true, the command runs and falsifies the condition. When the inverted condition is checked in the second command, it will always be true. Shulkerscript fixes this by using a mix of anonymous functions and data stores.
execute if block ~ ~-1 ~ minecraft:stone run setblock ~ ~-1 ~ minecraft:cobblestone# this will always execute because after the first command the block cannot be stoneexecute unless block ~ ~-1 ~ minecraft:stone run say Not on stone
Embedded Programming Language
Shulkerscript allows running Lua code during compilation and running the returned output in Minecraft, mcscript offers JavaScript modals.
fn execute() { run lua() { return "say hi"; };}
modaljs newModal(){ return "say hi";}
newModal()