Functions
Functions work similarly to regular .mcfunction
s, but contain extra utility to make them work more like programming functions. At its most basic level, a function can be used to create a new .mcfunction
file and place code in it.
Defining Functions
Functions are defined using the function
command. The command itself is very dynamic and accepts lots of different kinds of inputs; however, it always requires a function name.
A code block must always follow function definitions. The code in this block is what will go into the defined function.
Parameters
Functions can be defined with parameters, which must be specified whenever the function is called. Parameter definitions use the same syntax as values, but without the keyword define
. Functions are very flexible with how you can specify parameters, but the most widely accepted way is by placing them inside parentheses ()
and separating them by commas ,
.
The following example shows defining a function called "awardPoints" with a single parameter, being the number of points to award.
Optional Parameters
If you want to make a parameter optional, you need to give it a default value that will be specified automatically if it's omitted. This is done using the assignment operator =
, and the default value. Once you specify an optional parameter, every parameter that follows must also be optional.
The following example shows the "awardPoints" function with its "amount" parameter optional such that if the caller doesn't specify an amount, it will default to 1.
Using Folders
When defining a function, the dots .
in its name act as path separators for the folder it will go in. When the function is exported to an .mcfunction
file, it will be placed in the folder. The following example shows creating a function which will be placed in a subfolder:
The compiled function is then located at scoring/reset.mcfunction
. Using folders is a good way to group functions based on what they do, increasing clarity for both the writer of the code and the reader.
Calling Functions
Now that you have functions, you need to be able to use them. Running a function is also known as "calling" it. The syntax of calling a function is functionName(parameters)
.
If the function doesn't have any parameters (or its parameters are all optional), you still need the parentheses to tell MCCompiled that you want to call the function: functionName()
The following example calls the awardPoints defined in the earlier examples:
Return Values
Functions are able to send back a value after they're done running, called a "return value." Return values are particularly useful in cases where the function is a utility for other code to use.
Returning a Value
To return a value, use the return
command. This will set the value that will be returned when the function ends. The return command, as of 1.16, does not stop the function immediately, but this is planned for a future version.
This example shows a more complicated function which computes the highest score of any player in the game and returns it to the caller:
Type Consistency
If you have a return
command somewhere in the function, every return
command in that same function must return the same type. If you return a boolean somewhere in the function, you can't return an integer somewhere else.
Using Return Values
Using a return value is done by using the function call as if it were a value. The following example builds on the getHighestPoints
example shown above by using its return value. If the function returns more than 100, it's considered an "ultra-high score" and a title is shown to all players.
The title then calls the function again and displays its returned value in the message.
Exports
When a function is not used anywhere in your code, it is not included in the compiled output unless given the export
attribute. So, what constitutes a function being "used"?
Any code in the top-level of your file, as in, not inside any block, is always marked as used. Any function marked for export will propagate that to any of the functions it calls. Any functions marked with the auto
attribute are also marked as used.
In this example, only the function
a
is exported because it's the only one in use.If the top level call is changed to
b()
, then the functionsa
andb
are both exported.If the top level call is changed to
c()
, then the functionsa
,b
andc
are exported.
Attributes
Attributes can change the way functions behave. Any number of attributes can be applied anywhere before the name. See attributes for all attributes across the language.
- extern
Makes a function external. External functions cannot have code in them, and their parameter names are interpreted verbatim. These functions will call the
.mcfunction
that matches their name and folder, making them great for combining MCCompiled with optimized handwritten functions or code from non-MCCompiled users.Examples & Use-case
In cases where you have an
.mcfunction
file that cannot be ported or is not necessary to port over, it's better to declare an external function; making it possible to call the.mcfunction
directly.// BP/functions/library/example.mcfunction function extern library.example library.example()- export
Marks a function for export. The function and any functions it calls will always be exported whether they're in use or not. See more about usage/exports here.
Examples & Use-case
Excluding unused files is beneficial for many projects, but sometimes you'll have functions you run in-game through a command block, the
/function
command, or other methods MCCompiled doesn't know about. The export attribute covers those edge cases. In this example, the user wants to run/function reset
in game.function export reset { kill @e[type=item] itemsCollected[*] = 0 print "Reset everything!" }- auto
Makes the function automatically run every tick; or, if specified, at an interval. If the attribute is specified as-is, the function will be marked as "in use" and added to
tick.json
. If a parameter is given in ticks, the function will run on that interval using an auto-generated timer.Examples & Use-case
Anywhere
tick.json
is needed, or something needs to happen on a timer, the auto attribute saves lots of boilerplate code and clearly communicates which functions automatically run. In the example below, time suffixes are used instead of tick count.function auto everyTick { // logic to run every tick. } function auto(1s) everySecond { // logic to run once a second. }- partial
Makes a function partially implemented. When a function is partial, you can re-define it later as many times as you want, with each one appending its contents to the original function.
Examples & Use-case
Partial functions are useful with metaprogramming or forward declaration, where you may want to use a function before its actual implementation. The following example shows how a function can be defined in two different places with their results merged.
function partial example { print "One!" } function partial example { print "Two!" } example() // One! // Two!