配方与配置 DSL

基本信息

属性 值
解析器 net.bdew.lib.recipes.RecipeParser
执行器 net.bdew.lib.recipes.RecipeLoader
语法 AST ast-statements-cfg.scala / ast-statements-recipe.scala / ast-conditions.scala / ast-stackref.scala
入口方法 RecipesHelper.loadConfigs(modName, listResource, configDir, resBaseName, loader)
recipes/ Scala 文件数 15(含 gencfg/、lootlist/ 子目录)

功能

BD lib 内置了一套自定义文本 DSL,用于同时定义「机器调校参数」与「合成配方」。同一套解析器被复用于两处:本模组自己的网络白名单配置,以及下游模组的机器调校文件。

语句分类

AST 分为两个顶层分类(ast-statements-cfg.scala):

基类 用途 子类
ConfigStatement 配置作用域语句 CsRecipeBlock、CsConditionalConfig、CsClearRecipes
RecipeStatement 配方作用域语句 RsCharAssign、RsClassMacro、RsRecipes、RsConditional、RsRecipeShaped、RsRecipeShapeless 等

命名约定写在源码注释中:配置语句以 Cs 开头、配方语句以 Rs 开头、条件以 Cnd 开头(ast-conditions.scala:12-15)。

关键语法

语法 含义 AST 类型
{char} = {ref} 字符映射,把配方图案中的一个字母绑定到物品引用 RsCharAssign
def {id} = {name} 类宏,$id 可在类名处展开 RsClassMacro
recipes { {statements} } 配方块,用于分组与隔离 RsRecipes / CsRecipeBlock
clearRecipes: {spec} 清除此前为某产物定义的所有配方 CsClearRecipes
XXX XXX => {result} [* {count}] 3×3 有序配方 RsRecipeShaped
XX XX => {result} [* {count}] 2×2 有序配方 RsRecipeShaped
shapeless: {characters} => {result} [* {count}] 无序配方 RsRecipeShapeless

* {count} 后缀用于指定产出数量,默认 1。

条件表达式

ast-conditions.scala 定义了 6 种条件,全部以 Cnd 前缀命名:

语法 含义 AST 类型
HaveMod {string} 该 modid 存在时为真 CndHaveMod
HaveAPI {string} 该 API 存在时为真 CndHaveAPI
HaveOD {string} 该矿物字典条目存在时为真 CndHaveOD
! {condition} 取反 CndNOT
({c} && {c}) 与 CndAND
({c} || {c}) 或 CndOR

条件可同时用于两个作用域:配置作用域用 if {cond} << {statements} >> [else << {statements} >>](CsConditionalConfig),配方作用域用 if {cond} recipes { {statements} }(RsConditional)。

解析器的可扩展性

RecipeLoader.newParser()(RecipeLoader.scala:33)是一个可被子类覆写的方法,注释明确写明「override in subclasses to use an extended parser」——BD lib 自身的 NetworkSecurityLoader 就用 GenericConfigLoader / GenericConfigParser 混入了这套机制。

数值

数值名 值
ConfigStatement 子类数 3
RecipeStatement 子类数 6 个具体类(RsCharAssign、RsClassMacro、RsRecipes、RsConditional、RsRecipeShaped、RsRecipeShapeless)+ 1 个抽象基类 CraftingStatement
Condition 子类数 6
条件求值实现 RecipeLoader.scala:327-336(resolveCondition)
支持的有序配方尺寸 2 种(2×2、3×3)
无序配方种类 1
条件原语种类 3(HaveMod / HaveAPI / HaveOD)
布尔运算符 2(&&、||)+ 取反 !

交互

DSL 本身没有玩家交互。它是给模组作者和服务器管理员在 .cfg 文件里使用的编辑接口:

触发 行为
服务器启动、预初始化阶段 加载器按顺序解析配置文件并执行全部语句
配方语句 RsRecipeShaped 调用 Misc.addRecipe → GameRegistry.addRecipe 注册有序配方
配方语句(使用矿物字典时) 调用 GameRegistry.addShapelessRecipe / ShapelessOreRecipe 注册无序或矿物字典配方
clearRecipes: {spec} 移除先前注册的、产物匹配的配方
条件为假 对应块内的语句整体跳过
配置解析出错 抛出 StatementError,由 RecipesHelper.tryLoadConfig 捕获后经 FMLCommonHandler.raiseException 中止游戏

相关条目