函數(Function)是一個可包含多行指令的資料包檔案。作為一個文字檔案,函數可以很容易地進行修改,並且在執行大量指令時更不容易像指令方塊一樣造成延遲。
定義[]
函數是一個擴展名為.mcfunction
的文字檔案。其編碼應為ANSI或無BOM的UTF-8。
在以下結構圖中,以黑體著重標識了函數檔案所屬的資料包目錄:
- (資料包名字)
- pack.mcmeta
- pack.png
- data
- (命名空間)
- advancements
- (進度).json
- functions
- (函數).mcfunction
- item_modifiers
- (修飾器).json
- loot_tables
- (戰利品表).json
- predicates
- (述詞).json
- 更多資料夾…
- advancements
- (命名空間)
像其他的資料包檔案一樣,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
來取得這些資訊)。
格式[]
在.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
標籤中列出的函數將在世界載入時或者伺服器被啟動時執行。每當資料包重載時,這些函數也將被執行。
- 在
minecraft:tick
標籤中列出的函數將在每一刻開始時執行。隨著遊戲刻遞增,這些函數將反覆執行。
- 在
注:在minecraft:tick
標籤中的第一個函數將在minecraft:load
中的函數執行前執行。這意味著,假定minecraft:tick
中依次有tick1
、tick2
、tick3
,minecraft:load
中有load1
,則/reload
後函數的執行順序為:tick1
、load1
、tick2
、tick3
...
何時被調用[]
函數將在一遊戲刻內執行其中的所有指令。同時,如果一個函數是被其他的函數所引用,那麼它將同其父函數在同一遊戲刻執行。函數會使用函數調用者的指令環境,這包括指令的執行實體,以及執行位置、朝向、維度和基準點。無論函數中的指令的順序如何,對函數內發生的指令環境的變更都不會影響此函數內(及其子函數內)其他指令使用的指令環境,直到下一次迭代為止。在同一函數內,/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.12 | pre1 | 加入了函數。 | |||
pre3 | 函數中的指令不再允許以/ 開頭。
| ||||
現在僅能使用# 來注釋,不再允許使用先前的// 。 | |||||
pre4 | 加入了新的參數:[if|unless] [选择器] 。 | ||||
pre6 | 在指令中使用函數時,函數執行被跳過(執行條件不符)的情況現在被視為指令失敗。 | ||||
1.13 | 17w43a | 自訂函數被移動至資料包中。 | |||
17w45a | 函數在載入時就會被完全解析與快取。 | ||||
17w49b | 函數現在可以有標籤了。 | ||||
標記了minecraft:tick 的函數現在會在每一個遊戲刻的開始時執行。 | |||||
18w01a | 標記了minecraft:load 的函數會在載入(或重新載入)資料包後執行 | ||||
1.20.2 | 23w31a | 現在可使用反斜槓\ 作為行末字元,以便指令在下一行進行承接。
| |||
函數現在可以包括宏行,成為巨集函數。 | |||||
pre1 | 現在無論數值的類型如何,作為宏參數使用的數字在插入時都不會包含後綴。 |
參考[]
組件 |
| ||
---|---|---|---|
資料包 | |||
教學 |
版本 | |||||||
---|---|---|---|---|---|---|---|
開發週期 |
| ||||||
技術 |
| ||||||
多人遊戲 | |||||||
遊戲訂製 |
語言