Minecraft Wiki

除另有声明,转载时均必须注明出处若簡繁轉換出錯,請以遊戲內為準请勇于扩充与修正内容有兴趣逛逛我们的微博沟通交流,欢迎到社区专页需要协助,请在告示板留言

了解更多

Minecraft Wiki
Advertisement
Disambig gray  本文章介绍的是Java版中的函数。关于基岩版的函数,请见“基岩版函数”。关于函数的命令,请见“命令/function”。
Information icon
此特性为Java版独有。

函数(Function)是一个可包含多行命令数据包文件。作为一个文本文件,函数可以很容易地进行修改,并且在执行大量命令时更不容易像命令方块一样造成延迟。

定义[]

函数是一个扩展名为.mcfunction的文本文件。其编码应为ANSI或无BOM的UTF-8。

在以下结构图中,以黑体着重标识了函数文件所属的数据包目录:

像其他的数据包文件一样,functions文件夹也能包含若干子文件夹以组织更深的层级关系。在调用这些子文件夹内的函数时,也必须引用子文件夹名。

允许的命令[]

在函数文件中,单个命令的长度不受命令方块字符数上限32,500的限制,但是同一游戏刻运行的总命令数量受/gamerule maxCommandChainLength的限制(默认为65536)。超过此数量限制的命令将在运行时被忽略。

在单人或局域网世界中,与命令方块一样,函数可以执行任何权限等级不超过2的命令。

在默认的多人游戏,函数要运行的命令的权限等级不能超过设定在server.properties中的function-permission-level

用法[]

要使用函数,首先必须在[世界名称]/datapacks/[数据包名称]/data/[命名空间]/functions这个顶层文件夹中放置名为[函数名称].mcfunction文本文档,这个文档将包含此函数内所有需要执行的命令。注意它的编码,以便被Minecraft正常读取。如果是单人游戏,这个世界文件夹可以在.minecraft/saves中找到;如果是多人游戏,函数必须放置在每一个需要使用这个函数的世界文件夹中。这个顶层文件夹的名字将在调用其中函数时作为其命名空间。

在执行函数时,推荐写为严谨格式[命名空间]:[函数名称]。如果你可以确认你的函数不和其他现有函数冲突,则可以简写为[函数名称],程序将先遍历默认命名空间minecraft:中的函数名称,再检索其他命名空间。但是为了避免在未来的版本因为Mojang对默认命名空间的改动而导致意料之外的事,最好使用自定义的命名空间并明确地使用它。[1]当然,函数也可以被放置在这个顶层文件夹的子文件夹中。例如,如果需要调用datapacks/[数据包名称]/data/custom/functions/example/test.mcfunction的函数文件。则需描述为custom:example/test(相对路径)

如果对函数文件的内容或位置进行了修改,则可以使用/reload来重新从硬盘加载。这允许Minecraft识别函数文件的更改,而不必重新进入世界。

函数执行成功后将会在聊天栏显示信息:执行了函数[函数名]中的[数量]条命令。函数内部命令的成功与否并不能直接被比较器检测(虽然你还是可以通过/execute/scoreboard来获取这些信息)。

格式[]

TestingFunctions

测试函数系统。这个简单的函数使用了发送了3次/tellraw消息,执行了1次/give命令

.mcfunction文件中,每一行都允许一条不带前导正斜杠/的命令。玩家可以在行首添加#来注释单行文本。在每条命令的各参数间,不允许添加多个空格,但可以在一条命令的首末位置添加若干制表符和空格。

对于一行命令,如果在末尾使用反斜杠\,则允许在下一行添加后续部分。后续行的前后两端的空白会被截去,并尝试承接上一行命令。这提供了一种将单行命令拆分为多行书写的方法。

[]

通过使用$开头(作为非空白字符),即可标记此指令为宏指令。宏指令中可包含若干以$(变量)格式存在的参数。当执行/function (命名空间):函数 <arguments>命令调用包含宏行的函数时,会以<arguments>替换其中的参数。<arguments>中必须包含函数中每一个被调用的参数,但不一定每一个提供的参数都必须被调用,可以包含多余的。若替换后的命令无法解析,则整个函数会被跳过。

例如:

function foo:bar {key_1:"宏指令", key_2:10, key_3:"冗余参数"}

其中foo_bar的内容是:

say 这是一条普通指令
$say 这是一条 $(key_1)!
$teleport @s ~ ~$(key_2) ~

调用[]

函数可能以不同的方式从数据包中的其他文件调用。

通过命令[]

可以使用/function命令调用函数。

一个单独的函数可以通过其命名空间ID来调用。

不像其他的数据包文件,函数被标签支持,这允许它们能合为一组。/function也接受函数标签的命名空间ID,以便调用一系列函数。

通过进度[]

达成一个进度时,可以运行一个函数作为奖励。函数中命令的执行者是达成进度的玩家。

奖励函数在进度JSON文件中通过以下方式调用:

{
    "rewards": {
         "function": "命名空间:指向函数文件的路径"
    }
}

通过函数标签[]

函数可以通过数据包中的标签组合到一起。标签中的函数将以其定义顺序从上到下依次执行。如果同一函数多次出现,则只在首次出现时执行。

可以通过/function #(命名空间):标签命令来调用一个函数标签包含的若干函数。 例如:

function #example:example_tag

则调用了example命名空间下tags/functions目录中的example_tag.json文件中列出的所有函数。

另外,在minecraft命名空间下包含了两个拥有特殊行为的函数标签:

  • minecraft:load标签中列出的函数将在世界加载时或者服务器被启动时执行。每当数据包重载时,这些函数也将被执行。
  • 这些函数在玩家进入世界前就被执行,这意味着无法使用目标选择器来找到玩家。因此,诸如/tellraw/title的命令将不会对任何玩家显示。
  • minecraft:tick标签中列出的函数将在每一刻开始时执行。随着游戏刻递增,这些函数将反复执行。

:在minecraft:tick标签中的第一个函数将在minecraft:load中的函数运行前运行。这意味着,假定minecraft:tick中依次有tick1tick2tick3minecraft:load中有load1,则/reload后函数的运行顺序为:tick1load1tick2tick3...

何时被调用[]

函数将在一游戏刻内运行其中的所有命令。同时,如果一个函数是被其他的函数所引用,那么它将同其父函数在同一游戏刻运行。函数会使用函数调用者的命令环境,这包括命令的执行实体,以及执行位置、朝向、维度和基准点。无论函数中的命令的顺序如何,对函数内发生的命令环境的更改都不会影响此函数内(及其子函数内)其他命令使用的命令环境,直到下一次迭代为止。在同一函数内,/execute命令可以改变当前的命令环境,同时不对之后的任何命令产生影响。

例如:

execute as @a at @s run function foo:bar

其中foo:bar的内容是:

teleport @s ~ ~5 ~
setblock ~ ~-1 ~ minecraft:emerald_block
execute at @s run setblock ~ ~-1 ~ minecraft:diamond_block

这3个命令会将所有玩家向上传送5个方块、在玩家传送前位置的脚下放置绿宝石块,再于玩家传送后位置的脚下放置钻石块。这个特性不会影响到命令中出现的目标选择器参数。

在上例中,命令的环境参数依然将受到其各自的execute子命令的影响。

历史[]

Java版
1.12pre1加入了函数。
pre3函数中的命令不再允许以/开头。
现在仅能使用#来注释,不再允许使用先前的//
pre4加入了新的参数:[if|unless] [选择器]
pre6在命令中使用函数时,函数执行被跳过(执行条件不符)的情况现在被视为命令失败。
1.1317w43a自定义函数被移动至数据包中。
17w45a函数在加载时就会被完全解析与缓存。
17w49b函数现在可以有标签了。
标记了minecraft:tick的函数现在会在每一个游戏刻的开始时执行。
18w01a标记了minecraft:load的函数会在加载(或重新加载)数据包后执行
1.20.223w31a现在可使用反斜杠\作为行末字符,以便命令在下一行进行承接。
函数现在可以包括宏行,成为宏函数。
pre1现在无论数值的类型如何,作为宏参数使用的数字在插入时都不会包含后缀。

参考[]

语言

Advertisement