1 个不稳定版本
0.0.1 | 2023年11月17日 |
---|
23 在 #bedrock
26KB
448 行
mcfn - 一个 mcfunction 预处理器
[!注意] 此预处理器主要针对基岩版,可能不适用于Java版,因为它们的命令语法不同。
概述
理念
不同于为Java版发明一个全新的编程语言,如 mcscript,mcfn
通过扩展 mcfunction
格式以更易读的方式保存重复性任务。
mcfn
利用 execute
和 scoreboard
命令在 Minecraft 中模拟运行时环境。这允许使用多个宏进行动态条件编程。
安装
Cargo
cargo install -f mcfn
使用方法
要转换 functions
目录下所有的 *.mcfn
文件,可以使用以下命令。
mcfn functions/**/*.mcfn
参考
缩进
在构建文件中,程序中每行的前导空格将被删除。这允许在代码块中嵌套代码,以获得更好的视觉效果。
#!proc greet
say Hello
say World
#!end
#!! can be written like below as well
#!proc greet
say Hello
say World
#!end
注释
有两种不同类型的注释。一种注释以一个井号(#
)开头,如通常一样,但不能跟一个感叹号(!
)。它们包含在构建文件中,可以在可以使用完整命令的任何地方使用。事实上,它们可以在命令的末尾使用。另一种注释以一个井号和两个感叹号(#!!
)开头。它们必须作为整个行使用,这意味着它们不能附加到宏或命令。
with
with
宏在代码块的每一行前添加其参数。
#!with execute as @a
say Hello
say World
#!end
#!! same as
executa as @a say Hello
execute as @a say World
proc
和 call
proc
宏创建一个过程。它的内容可以在程序的稍后位置通过使用 call
宏多次调用。
#!proc greet
say Hello
say World
#!end
#!call greet
#!call greet
与大多数编程语言不同,过程总是全局的,这意味着可以在不同的过程中定义一个过程,只要调用在过程定义之后存在,就可以从外部调用该过程。
#!call foo
#^^^^^^^^^ error
#!proc foo
#!proc bar
say Hello
say World
#!end
#!end
#!call bar
过程不能有参数。然而,你可以实现如下所示的行为
scoreboard objectes add _internal dummy
#!proc fizzbuzz
#!if scores @s _arg_a matches 3
#!then
say Hi
#!else
say Hello
#!end
#!end
scoreboard players set @s _arg_a 3
#!call fizzbuzz
scoreboard players reset @s _arg_a
scoreboard players set @s _arg_a 20
#!call fizzbuzz
scoreboard players reset @s _arg_a
log
log
宏在它被到达时将在编译时将它的值打印到控制台。这可能对调试很有用。
#!log hi
if
、ifn
和 else
你可以使用 if
来验证条件是否满足,并使用 ifn
来验证相反的情况。如果有多个 if
或 ifn
宏链式调用,则当 其中一个 条件满足时执行该块。
#!if score @s foo matches 3
#!ifn score @s bar matches 5
#!then
say Hello
say World
#!end
你还可以添加一个 else
块,如果没有任何条件满足,则将运行该块。
#!if score @s foo matches 3
#!ifn score @s bar matches 5
#!then
say Hello
say World
#!else
say Bye
say World
#!end
include
你可以使用 include
宏相对于当前文件包含另一个文件。
#!include path/to/file.in
请注意,包含 mcfn
文件将不会被渲染,因此你只能与不最初需要编译的 mcfunction
程序一起使用(如果该步骤在包含文件之后发生)。
此宏也可以用来包含某种类型的标题,例如通过创建仅由注释组成的 mcfunction
程序来实现。
declare
和 delete
通过使用 declare
宏可以快速创建分数。使用 delete
宏可以删除分数。
#!declare x
#!delete x
结果将是
scoreboard objectives add x dummy
scoreboard objectives remove x
when
和 else
如果你以前使用过像 C 或 Rust 这样的编程语言,你可能熟悉条件编译。条件编译允许你根据配置设置或操作系统等构建可变程序。
if cfg!(any(target_os = "windows", target_os = "linux")) {
// do performant stuff
} else if cfg!(any(target_os = "android", target_os = "macos")) {
// do less performant stuff
}
这也可以通过使用 when
宏在 mcfn
中实现。
#!when MCFN_TARGET windows
#!when MCFN_TARGET linux
#!then
say Hello
#!else
say Hi
#!end
这些条件将指定的环境变量(如 MCFN_TARGET
)与字符串(如 windows
)进行比较。当条件满足时渲染该块,否则忽略(如果环境变量未定义也是如此)。其结构与 正常条件 相匹配,只是使用 when
而不是 if
,并且不存在取反的 when
宏。请注意,when
分支仍然会运行 log
和 include
宏并验证块。在编译步骤中,将忽略 已渲染 的块。
然后你可以通过使用例如以下语法通过 bash 控制编译
MCFN_TARGET="windows" mcfn script.mcfn
需要了解的知识
高亮显示
预处理语言被设计为与 mcfunction
高亮显示器一起看起来很好,因此你可以在你的存储库中使用它。因此,.mcfn
和 .mcfn.mcfunction
都支持作为文件扩展名。
魔法变量
分数 __mcfn_internal_n
(其中 n 可以是任何自然数)和“假玩家”名称 __mcfn_internal
由 mcfn
使用,不应在程序中使用,否则可能会导致意外的行为。
在 Allay 中的使用
将以下 ruby 脚本添加到你的脚本目录,并在 allay.toml
中引用它。
# TODO
依赖项
~1.3–1.9MB
~35K SLoC