There's so much Chinese literary/philosophical stuff in this pack, and with how the Patchouli book is formatted, there's just no way to do an English translation. Sorry about that!
Part 1 · Guide
Minecraft 1.20.1, Forge loader.
All story and guidance are written in the Hex Notebook that is generated together with the world.
The modpack centers on Hexcasting and builds its own world view. Through deep modding, every mod and mechanic is woven into the narrative.
The pack is conceived as a base pack: it can be played on its own, and you may also add many other non-Hex mods; otherwise, refer to the Modding Guide below for compatibility. With this in mind, no unnecessary optimizations have been introduced.
The README explains in detail the inner workings of hexes in the game, and the in‑game notebook provides further instructions on casting procedures and detailed patterns. The following appendix includes complete materials that can guide an AI in generating KubeJS patterns. Adding mods and writing modding code is itself part of the pack’s gameplay, just as the story says: Akasha is the nature that belongs to them; the Book of Eternity is the I defined by me.
Part 2 · Overview
In the introduction to this modpack, to do what other introductions habitually do—first deliver a lofty discourse, then list every mod’s function as a feature, and finally emphasize the character of the modifications (if any)—would be superfluous and contrary to its purpose.
For the modifications that occupy the bulk of this pack are precisely meant to create a whole; only on the path toward truth do they reveal their true meaning. If the introduction that follows is regarded not merely as the beginning of knowledge but as actual knowledge, then it becomes a ruse to evade the matter itself.
You will discern logic in obscure fragments, recognize nature in the logical hexes, and finally discover that the truth of everything is nothing other than your own developing cognition.
Part 3 · Essence
The reason for adopting the form of a game is that it requires the author and the player to overlap and split within the same subject: the all‑knowing author forgets once more, then re‑experiences the genesis of knowledge.
The first stage is recognizing nature. The player learns hexcasting and interacts with the logical structure of the world through concepts. At first, consciousness takes hexcasting as a one‑way manipulation of nature, but when the player discovers that the logic of hexes and their own thinking are in fact isomorphic, nature is recognized as consciousness itself. Thus self and nature lose their balance, and the latter begins to collapse into the former.
The second stage is encountering the intermediary. The unified world is thoroughly broken; the consciousness of villagers is stripped by the player into the Budding Amethyst, refined into pure energy, and wisps of independent thought are created. When the wisps exhaust the logic of nature, the player simultaneously realizes: The spirit I created has at last borne witness to me—I am the Creator. Causality no longer follows a linear flow; the player sees the logic that creates and witnesses past and future, where beginning and whole confer meaning upon each other—and he is about to see himself.
The third stage is creating the self. When the definition of “I” comes from a created other, the self is no longer something that has always been so. Player, author, the true self in eternity—the true self is the essence of both player and author, and where then does this essence go? The sun at noon is already setting; things dying are being born. Life and death are each other’s essence, and yet the essence does not lie within the two. The player in history and the author in logic are merely two poles eternally split and eternally longing for each other; the so‑called all‑embracing true self above them turns out to be nothing but a rift of love and curse between the two.
The history behind the curtain steps onto the stage; between backstage and frontstage is a round trip. Nature accomplishes reason through necessity, and thus is the world of spirit.
And thus is the world of spirit. Nature accomplishes reason through necessity. Between frontstage and backstage is a round trip; the logic on the frontstage steps onto the stage.
……
Wish you fun playing with yourself.
咒术机理的书写艺术
第一章:咒术
part.1,指引
-
Minecraft 1.20.1,Forge 加载器。
-
所有剧情与指引,均写于世界生成时自带的咒术手册中。
-
整合包以咒法学为核心,世界观自行构建。通过深度魔改,将所有模组与机制整合到叙事之中。
-
整合包的定位是基础包,可单开,也可加入其他诸多非咒法模组,否则需要参考下文的魔改指北进行兼容。考虑到这一点,未添加任何不必要的优化。
-
README 文档详细阐述了游戏内咒术的运作机理,游戏内手册在此基础上提供了施法流程及详细图案的说明,后文附有可指导 AI 生成 KubeJS 图案的完整资料。添加模组、魔改代码本身就是本包玩法的一部分,恰如剧情所说:阿卡夏是属于他们的自然,永恒之书是由我定义的我。
part.2,概要
在这个整合包的介绍里,如果也像其他介绍里惯常所做的那样先做一番高屋建瓴的论述,再将每一个模组的作用作为特色列出,最后着重阐明魔改的特色(如果有的话),毕竟是多余的,也是不合目的的。
因为,在这个整合包中占主要篇幅的魔改部分,正是为了创造一个整体,只有在追寻真理的道路上,他才展现出他真正的意义。如果后文的介绍不被仅仅视为认识的开始,而是作为实际的认识,那么他就成了躲避事情自身的一种巧计。
你将在晦涩的残篇中辨识逻辑,在逻辑的咒法中认出自然,最终发现一切的真理不是别的,而只是你发展着的认识而已。
part.3,本质
之所以采取游戏的形式,是要求作者与玩家在同一主体中重叠而分裂,知晓一切的作者再次遗忘,然后重历认识的发生。
第一环节是认出自然。玩家学习咒法,以概念的方式与世界的逻辑结构相交互。起初,意识将咒法理解为对自然单向的操作,但是,当玩家发现咒术的逻辑与自身的思维其实同构,自然便被认作意识本身。于是,自我与自然不再平衡,后者开始朝前者坠落。
第二环节是遭遇中介。同一的世界被彻底打破,村民的意识被玩家剥离在母岩之中,提炼为纯粹的能量,创造出独立思维的咒灵。当咒灵穷尽自然的逻辑,玩家也随之发现:由我创造的精神终于证成了我,我是创世神。因果不再遵循线性流转,玩家看见过去未来创造证成的逻辑,开端与整体互相赋予意义,他即将看见自己。
第三环节是创造自我。当"我"的定义来自被创造的他者,自我便不再是一个从来如此的事情。玩家,作者,永恒中的真我,真我是玩家与作者的本质,本质又当何去何从呢?日方中方睨,物方死方生,生死作为对方的本质,本质又岂在二者之中。历史中的玩家与逻辑中的作者,不过是永恒分裂而又永恒相思的两端,所谓其上包罗万象的真我,原来是二者间,一道爱与诅咒的裂隙而已。
幕后的历史登上了舞台,幕后与幕前是往返之间。自然藉以必然完成理性,而精神的世界原来如此。
而精神的世界原来如此。自然藉以必然完成理性。幕前与幕后是往返之间,幕前的逻辑登上了舞台。
……
祝愿你与自己玩的开心。
第二章:机理
part.1,序言
咒法的执行系统是一个函数式虚拟机在Minecraft中的实现,分三层架构:
- 咒法虚拟机 - CastingVM:负责管理执行流程,包括执行栈的推进、转义处理、错误处理、副作用的调度应用。
- 咒法映像 - CastingImage:记录当前咒法的所有内部状态,包括数据栈、括号状态、操作计数和自定义数据,将其封装与序列化保存,所有状态字段均不可变,每次执行产生新实例。
- 施法环境 - CastingEnvironment:咒法执行与世界交互的接口,定义施法者和条件,负责资源管理、权限检查、范围验证和反馈。
施法时,依次进行初始化,元运行与持久化。
首先是初始化阶段:
- 创建初始咒法映像
- 创建施法环境实例
- 结合二者构造咒法虚拟机
- 传入要执行的 iota 列表
之后便在虚拟机中进入执行阶段,虚拟机将 iota 列表包装为执行帧,推入执行栈。然后进入主循环。
只要执行栈非空且未提前退出,则:
- 取出执行栈顶的执行帧
- 从执行帧中取出下一个待执行的 iota,进行内部执行
- 处理括号系统,如果未被转义,则匹配图案并执行
- 返回施法结果,包含新状态、新执行栈和副作用列表
- 更新咒法映像和执行栈
- 应用副作用,如有事故则提前退出
之后便在咒法映像中进入持久化阶段,施法环境和咒法虚拟机状态不保存,每次施法时将重新创建。
咒法映像则将序列化为 NBT 数据保存,若创建初始化阶段创建咒法映像时存在保存的映像,则将其读取并解析。
以上便是三层架构与三个阶段的概括说明,然后是对于三层架构的详细说明,并结合元运行等核心图案进行解析。
part.2,施法环境
施法环境是咒法执行与世界交互的抽象接口,负责:
- 获取施法者与施法手
- 进行媒质提取与物品操作
- 进行范围验证与权限验证
施法环境通过组件架构支持功能扩展,每一种操作都隶属于以下四个组件之一:
- 图案执行后处理
- 施法结束后处理
- 媒质提取前/后处理
- 范围检查处理
施法者的施法环境由施法者,施法手,施法范围和哨位影响半径组成。判断范围时,优先判断范围是否在卓越哨位的半径之中。
消耗媒质时,遍历施法者身上的媒质源进行提取;如果不足,则尝试消耗生命值进行提取,然后根据消耗后生命的差值计算转化出的媒质量。施法者的施法环境由法杖施法环境与造物施法环境扩展,又与法术环施法共同扩展施法环境。
法杖施法环境执行时:
- 将笔顺匹配为图案
- 获取法杖虚拟机实例
- 应用图案 iota 的执行
- 如果栈清空,清除咒法映像和图案列表,否则保存
造物施法会先尝试优先在造物中提取所需的媒质,然后再从玩家身上提取。法术环施法时,无主法术环视为已被启迪,施法手视为主手。绑定施法者后,扩展其施法范围。
part.3,咒法映像
咒法映像记录咒法虚拟机的完整状态,所有字段均为只读,不可修改。更新通过复制以创建新实例,其中包含六大部分。
将完整状态序列化为 NBT 数据时,在上述六种信息中,括号内 iota 和转义标记将分别存储。如果括号内的 iota 列表过大无法序列化,将会替换为空列表。从 NBT 数据恢复为咒法映像的过程同样分为六个环节。
咒法映像数据:
- stack: 栈中的 iota 数据
- parenCount: 当前括号深度
- parenthesized: 括号内暂存的 iota 及转义状态
- escapeNext: 下一个 iota 是否将被转义
- opsConsumed: 操作计数
- userData: 用户数据,包含渡鸦之思和驱动标记。
数据恢复环节:
- 反序列化数据栈 - 遍历 stack 列表,对每个数据尝试解析为 iota
- 反序列化用户数据
- 反序列化括号内容
- 读取括号深度,转义标记和操作计数
- 创建咒法映像
- 异常时记录事故,返回空映像
part.4,咒法虚拟机
咒法虚拟机由咒法映像与施法环境共同构造,根据输入的 iota 决定咒法映像的下一次迭代。咒法映像执行过程中会被更新;施法环境不可变,用于与世界交互。
传入图案列表和当前世界便可开始执行:创建空栈,将输入的 iota 列表包装为执行帧推入栈顶,只要执行栈非空且未提前退出,则判断栈顶帧是否可执行且大小正常,执行并返回结果,更新咒法映像与执行栈。
虚拟机处理执行帧时:
- 检查列表状态,若列表非空,则取出首个待执行图案;若为空,则返回结果。
- 准备后续执行,若列表中仍有剩余图案,则将剩余部分包装为新的执行帧,推入延续栈。
- 执行当前图案,调用虚拟机内部执行,执行列表中的首个图案,并获取执行结果。
- 返回执行结果,将更新后的咒法映像、延续状态及副作用列表封装为施法结果返回。
在虚拟机的内部执行中,首先进行括号系统的处理,若已被括号系统处理,则返回处理结果,不进行图案匹配。若未处理,对于图案 iota,则进行图案匹配和执行。所有异常在内部捕获,并转换为事故被处理。
括号系统内含三个参数,代表当前打开的括号深度,括号内暂存的 iota 及其转义状态,和下一个 iota 是否将被转义。
系统会将输入的 iota 转换为图案 iota,并提取其角度值用于匹配考察等特殊图案。考察或探知将为系统添加一次性的转义状态,被转义的 iota 在被运行时不会匹配为图案。当括号数归零时,括号内暂存的 iota 列表将作为列表 iota 压回,并结束括号状态。
元运行的奥秘由此便明了。赫尔墨斯之策略创建一个施法边界,卡戎之策略的停止效果也最多至此。然后将栈顶的图案列表包装为执行帧压入延续之中,厄科之策略不过是压入指定数目。
托特之策略创建的则另一种特殊的遍历帧,从第二次执行开始将上次代码执行后的栈状态存入累加器,恢复基准栈状态,确保每次迭代在相同初始条件下进行。每次迭代取出起始元素处理为执行帧,剩余数据与新基准栈封装为下一迭代帧。
伊西斯之策略的书签 iota 就是延续,包含当前与所有将要执行的帧,当其被运行时,则将当前延续替换为记录的延续。
修普诺斯之策略则创建了一个新的咒法虚拟机,若施法环境属于为玩家基础施法环境,则由此创建法杖施法环境;若不是玩家基础类,则继承原环境。由此环境构造虚拟机,同时从当前咒法映像中读取用户数据,并传入虚拟机中。
第三章:书写
然后是书写。在画布上连缀,在世界中构建。我将演示创造逻辑的过程:注册笔顺和名称,联系事件与函数,最后将其写入手册。
part.1,注册部分
-
打开网页 https://master-bw3.github.io/Hex-Studio/ ,设计你的图案,并记住起始笔顺的方向。以测试图案为例,起始笔顺沿东北方向,设计完成后,选择复制界面 Export Patterns 选项即可导出,复制其中格式如 "dew" 的笔顺。
-
打开文件 kubejs\startup_scripts\pattern\name.js,写入:
// 测试图案 registerPatternWrap('dew', HexDir.NORTH_EAST, 'test')
此步骤已完成
-
图案笔顺注册说明:
- registerPatternWrap 函数中依次填入笔顺,方向和注册名。
- EAST 代表起始笔顺方向为正东,SOUTH_WEST 则指向西南,此不枚举。
- 卓越标签于 kubejs\server_scripts\patterns.js 文件中统一处理。
- 由于上文注册函数的封装,因此图案的完整命名空间 ID 即为 "homo:head"。
- 此处命名空间 ID 最好不要过长,也不要与已有的 ID 重复,以方便 hexParse 的查找。
-
打开文件 kubejs\assets\hex_playground\lang\zh_cn.json,写入:
"hexcasting.action.homo:test": "萌新之策略"
命名依据咒法学的操作命名法,json 文件难以添加注释,此不强加。
part.2,事件部分
注册图案对应的事件部分以 KubeJS 写就,书写难度各不相同,难以预测。
事件中涉及原版 KubeJS 与 JavaScript 的部分使用 AI 生成表现较好,但若未提供对应接口,则往往需要提供大量对应的源代码并进行 loadClass,从 KubeJS 的实际运用来看,这算作较为高阶的技巧,萌新可能需要时间掌握。
面向没有魔改基础的萌新来说,一个训练有素的 AI 可以帮你解决 80% 的问题。对于常规的事件书写,你的资料库里应该包含:
- 咒术笔记的第二章:咒术
- 咒术笔记的第三章:书写
- kubejs\startup_scripts\pattern\spell.js 文件,用于寻找可用方法与此文件中未包含的特例
- kubejs\startup_scripts\pattern.js 文件,若事件中有函数则需选择(可选)
- kubejs\startup_scripts\Imports.js 文件,若事件中有引包则需选择(可选)
- kubejs\server_scripts\patterns.js 文件,若事件需要服务端协同运行则需选择(可选)
- 咒法学仓库 Common/src/main/java/at/petrak/hexcasting/api/casting/eval 文件夹中 README.md 文件提及的几个文件,若事件为元运行则需选择(可选)
1. 书写规则:
- 不可使用 const,一律使用 let。
- 遍历复合标签时可选择 iterator()。
- 提示生成法术时,默认只生成事件部分,不生成注册部分和手册部分。
- 每次生成法术时不可更改图案 ID,若用户未提供图案 ID,则默认为"test"。
- 当用户提示输出日志时,仅打印事件中获取的部分关键值,避免使用新方法导致报错。
- 部分 ES6 语法在 KubeJS 中报错,如展开运算符[...list],使用 ES5 语法即可。
- 当用户所需的事件中存在未提供的刚需方法且未检索到方法原文时,在回答开头说明缺失的方法并提出可能的解决方案,直至用户确认解决方案后再给出完整代码。
- 联网搜索网址 https://kubejs.com/wiki ,自动查找不确定的方法,版本为 1.20.1,加载器为 forge,不考虑 KubeJS 扩展,不可搜索其他网址,wiki 上未找到的方法于开头警告。
- 非可变参数的情况下,一律使用 args.type(n) (type = bool/entity/vec3/list.list/double/string)获取参数,不可使用args.get(n),因为后者需要额外的判断与转化,相较于封装好的前者没有任何优势。
- 当用户所需的事件中包含 let args = new Args(stack, m), args.get(n) 的可变参数时,对于报错 throw MishapInvalidIota.of(args.get(n), m - n - 1, 'class.test'),在开头提示用户自行补全即可,无需写出报错具体内容。
- 当且仅当:
- 需要获取玩家绑定物元数据
- 需要返回的 iota 为图案 iota
- 事件内需要获取生物状态效果字符串 ID
- 需要进行 iota 的序列化存储与反序列化
- 在可变参数的同时要求针对栈顶数个 iota 类型改变入栈参数的数量,
则在通用模板之外,参考特殊情况
2. 对应法术:
打开 kubejs\startup_scripts\pattern\spell.js,创建:
// 萌新之策略
"test": (stack, env, img, cont) => {},
这其中的操作便对应于图案:"homo:test",此后每当绘制笔顺dew,便将执行其中操作。
3. 通用模板: stack, env, img, cont 四个参数分别对应执行栈,施法环境,咒法映像和延续,通常情况下,仅用前两个参数。于是,我们有:
// 萌新之策略
"test": (stack, env, img, cont) => {
// 打印四个参数
console.log([stack, env, img, cont])
// 此处的施法者或为咒灵,或为玩家,或为促动石等
let player = env.caster
// 故此,若不加判断强行从促动石处获取server,则将报错
let server = env.caster?.server??Utils.server
// 从施法环境中获得世界信息,依据施法者当前维度,这三个基本参数依照需求获取
let level = env.world
// 封装的方法,用于获取栈顶 n 个元素
let args = new Args(stack, 2)
// 获取栈顶向下第二元素,也即第一个输入的元素的 vec3 方法,若不属于 Vec3Iota,则自动抛出类型错误
let vec = args.vec3(0)
// 此两种方法用以确认目标位置是否在施法范围内。AI 不应考虑此方法,只需提醒用户自行按需补齐。
// ActionJS.helpers.assertVecInRange(env, vec)
// ActionJS.helpers.assertEntityInRange(env, entity)
// vec3 应当使用方法 vec.x() 获取其值,不可使用 vec.x
let blockPos = new BlockPos(
Math.floor(vec.x()),
Math.floor(vec.y()),
Math.floor(vec.z())
)
// 提前生成一个空的副作用列表,如果用户没有表示需要消耗媒质或生成粒子效果,则忽略这一步
let sideEffects = []
// 获取第二个输入的元素,也即栈顶元素,不对其进行操作,不会主动抛出类型错误,往往用于可变参数的情况,正常情况下不可使用此方法。
let iota = args.get(1)
// 可变参数讨论
if (iota instanceof EntityIota) {
// 移除生物
iota.entity.remove("killed")
// 添加副作用,副作用列表当中包含两种,一种是消耗媒质,一种是生成粒子,依照如下格式即可
sideEffects.push(OperatorSideEffect.ConsumeMedia(Math.ceil(100000)))
sideEffects.push(OperatorSideEffect.Particles(ParticleSpray.burst(blockPos, 5, 100)))
} else if (iota instanceof DoubleIota) {
// 向栈中压入 iota,内容为 args.get(1)
stack.push(iota)
// 向栈中压入 iota,类型为 null,注意,这是压入 null 的统一写法
stack.push(NullIota())
// 向栈中压入 iota,类型为布尔值,内容为 false
stack.push(BooleanIota(false))
// 向栈中压入 iota,类型为数字,内容为栈顶向下第二元素的数
stack.push(DoubleIota(iota.double))
// 向栈中压入 iota,类型为字符串,内容为栈顶向下第二元素的数,注意,这是压入字符串的统一写法
stack.push(StringIota.makeUnchecked(iota.double))
// 定义字符串
let string = "hello world"
// 函数 RL 的作用是去除字符串两端可能有的双引号或单引号,在对比输入字符串时应先行处理,对用户更友好
let rl = RL(string)
// 向栈中压入 iota,类型为列表,内容为 null 和字符串 hello world
stack.push(ListIota([NullIota(), StringIota.makeUnchecked(rl)]))
} else if (iota instanceof ListIota) {
// ListIota 并非列表,我们需要再次使用它的 list 方法
let input = iota.list.list
// 简单的遍历,将列表中所有元素压入栈中
let output = []
for (let i = 0; i < input.length; i++) {
let out = input[i]
stack.push(out)
}
} else {
// 打开 kubejs\assets\hexcasting\lang\zh_cn.json 自定义报错信息
throw MishapInvalidIota.of(args.get(1), 1, 'class.test')
}
// 若定义了副作用,则于此返回,否则忽略
return sideEffects
// 若非元运行法术,即直接压入帧或延续的法术,则无需额外返回,常规返回已在函数中封装完毕。
}
4. 特殊情况
1. 生成图案 iota:
let escape = PatternIota(HexPattern.fromAnglesUnchecked("qqqaww", HexDir.WEST))
2. 序列化与存储:
let iota = args.get(0)
let serializeIota = new CompoundTag()
serializeIota.put('iota', IotaType.serialize(iota))
let persistentIota = server.persistentData.getCompound('hexTags')
persistentIota.put('test', serializeIota)
server.persistentData.put('hexTags', persistentIota)
3. 反序列化与读取:
if (server.persistentData.contains('hexTags')) {
let hexTags = server.persistentData.getCompound('hexTags')
let test = hexTags.getCompound('test')
let serializeIota = test.getCompound('spell')
let iota = IotaType.deserialize(serializeIota, level)
}
4. 获取玩家绑定物元:
let player = env.caster
if (player == null) throw MishapBadCaster()
if (!player.isPlayer()) throw MishapBadCaster()
let userData = img.userData
let boundStorage
if (userData && userData.contains(MoteIota.TAG_TEMP_STORAGE)) {
boundStorage = userData.getUUID(MoteIota.TAG_TEMP_STORAGE)
} else {
boundStorage = MediafiedItemManager.getBoundStorage(player)
if (!boundStorage) throw MishapNoBoundStorage()
}
if (MediafiedItemManager.isStorageFull(boundStorage) != false) throw MishapStorageFull(boundStorage)
5. 获取状态效果 ID:
let potions = entity.getActiveEffects().toArray()
let size = potions.length
let effectId = []
for (let i = 0; i < size; i++) {
let result = String(potions[i]).substring(7)
let xIndex = result.indexOf(' x ')
if (xIndex !== -1) {
result = result.substring(0, xIndex)
}
let commaIndex = result.indexOf(',')
if (commaIndex !== -1) {
result = result.substring(0, commaIndex)
}
let dotIndex = result.indexOf('.')
if (dotIndex !== -1) {
result = result.substring(dotIndex + 1)
}
effectId.push(result)
}
6. 可变参数 - 进阶版:
let size = img.getStack().size()
if (size < 1) throw MishapNotEnoughArgs(1, size)
let pre_first = img.getStack().get(size - 1)
let result
if (pre_first instanceof DoubleIota) {
// 若使用 new Args(stack, 1) 则移除栈顶参数
let args = new Args(stack, 1)
let double = args.double(0)
result = double
} else if (pre_first instanceof StringIota) {
// 否则不移除栈顶参数
result = pre_first.string
} else if (pre_first instanceof BooleanIota) {
// 不引用时亦可移除
let args = new Args(stack, 1)
result = pre_first.string
} else throw MishapInvalidIota.of(img.getStack().get(size - 1), 0, 'class.test')
part.3,调试部分
通常来讲,法术往往需要多次测试,报错,分析,查找与修改才能达到令人满意的效果,因此,调试是极为常见,也是至关重要的一环。
- 测试,指在生成代码过程中让 AI 加入日志信息
- 报错,指在实际游戏使用之中出现与预期不符的结果
- 分析,指系统的描述报错结果并将日志丢给 AI 分析存在的问题
- 查找,指若需要使用的方法不能在 KubeJS 的维基百科上找到,则首先在其他的资料中进行查找
- 若找到数个可能的结果
- 或未找到对应的结果,则推测出数个可能的结果 生成一个测试代码,用 try catch 块对每一个结果进行验证
- 最后是修改,然后进入下一个循环
AI 往往尝试一次写出完整运行版本,这往往是不可行的。因此在写完代码后必须反思,这里用了哪些可能不对的方法,然后将该方法在此事件中的运用结果简略的打印出来,以便后续分析。
根据作者的要求不同,AI 应选择 player.tell() 或 console.log() 进行打印,默认选择后者。
AI 在调试时往往尝试获取更详细的信息,并对已有的信息进行处理,结果由于方法错误导致无法运行。因此 AI 在打印代码时不应主动尝试新方法,除非得到作者允许。
图案注册部分不可热重载,事件部分可以使用 /kubejs reload startup_scripts 在游戏内重载,手册和命名部分则可通过 f3 + t 重载。
part.4,手册部分
常规情况下,手册部分应该由用户自己书写,AI 请自动忽略。
打开 kubejs\assets\hexcasting\patchouli_books\thehexbook\en_us\entries\patterns,注意到其中除去诸多条目之外,有 stack,spells 与 great_spells 三个文件夹。诸多条目中,空条目的作用是移除手册中对应名称的条目,普通条目的书写则请自己参考帕秋莉手册的 wiki。
譬如,若希望将 萌新之策略 注册到 栈操作 - 常量 的页面中,则需要
-
打开如下文件:
kubejs\assets\hexcasting\patchouli_books\thehexbook\en_us\entries\patterns\stack\consts.json
-
写入:
{ "type": "hexcasting:pattern", "op_id": "homo:test", "anchor": "homo:test", "input": "vec, entity | double | list", "output": "many", "text": "依据参数演示图案注册的基础用法" }
-
具体到可变笔顺图案以及其余帕秋莉手册格式,则请自行参考。
第四章:艺术
1. 媒质篇节选
相较于其他华丽的魔法,咒法更可以被称之为自然的艺术。咒法与艺术都表达于感性,凝结于概念,最终实现于语言。
据官方所言,咒法是运用媒质的技艺:将概念以符合逻辑的方式表述为咒术,以使得产生于意识的媒质单向的作用于自然;概念承载于媒介以特定方式绘成的图案,而逻辑又由整体的目的与图案的限制共同界定。
譬如,"告知我沿视线方向所看向方块的位置向量",以咒术语言表述,则需依次绘制:
- 施法者,意识之精思
- 眼部位置,司北之纯化
- 施法者,意识之精思
- 视线方向,照准之纯化
- 在某位置沿某方向视向的方块坐标,弓箭之馏化
- 告知于我,揭示
据我考察的残页来看,具体到逻辑部分,还有一些术语如栈和 iota 等,有待深入学习。但由于相关于媒质的资料缺失,研究只能被迫终止。
正常的思考只能产生(或外溢,残页语)极少量的媒质,因此仅凭自己难以施法。但记载中,地下似乎出现过一种特殊的母岩,媒质会在其上缓缓生长为晶体。(ps:历史中从来没有进一步的文本,莫非自然能在梦中给予启迪?)
2. 洪范篇节选
简而言之,施法是将咒术语言运行的过程。使用法杖绘制图案,将图案依照一定的逻辑便可连缀成咒术,此时可以将之运行或者存储,保存的咒术可以在法杖或其他元件中运行。
具体来讲,手持法杖并使用,便会浮现一面六边形网格排列的点阵,并自动创建一个新的施法栈。
栈可以类比于收纳袋:将铜锭、铁锭、金锭依次放入,若想拿出铜锭,则必须先依次拿出金锭和铁锭。
这最后放入的金锭便是栈顶元素。栈操作便是在有序的线性资料集合的一端,即栈顶,进行:加入数据,即入栈;移除数据,即出栈;校验或修改数据,即检视的运算。绘制时,栈中元素会显示于左上角,绘制图案时会将元素依次压入栈中,故最顶部的元素即为栈顶元素,也即最后放入的元素。
在点阵上单击并在网格间拖动线条,依照一定的笔顺便可连接成有意义的图案,绘制出的图案会立即对栈或世界执行相应的操作并消耗可能的媒质。若操作完成后栈内为空,则退出施法并清空网格。
按住潜行时使用法杖亦可清空施法栈,Esc退出施法则不会。手持质念法杖左击方块可以清空画布,但保留栈中的iota。一个施法栈中同一时间最多容纳1024条数据,列表中的数据也将计入。
这些,数据,或是名与影,我暂且称之为iota,元素。iota具有不同的形式,我所知的有9种,其中细节甚多,稍后专门整理。
这些iota本身的操作并不同样遵循先入后出的法则,譬如在列表中,元素依照先后放入的顺序会被赋予从零递增的下标,操作时可以直接修改指定下标的元素。大多法术依据栈顶的参数对世界施加影响,而所有的栈操作,都通过iota的入栈、出栈和检视来完成。
- 揭示会检视栈顶的一个iota,然后告知于施法者
- 意识之精思会入栈一个代表施法者的实体iota
- 弄臣之策略交换栈顶两个元素的顺序,则是通过出栈两个iota并以相反顺序依次返回完成的
- 司南之纯化会检视栈顶的iota,若类型为实体,则令该iota出栈,然后入栈一个代表实体足部位置的向量iota
大多法术最多影响距我半径64格的范围,否则便会发生事故。例外的,施法者的iota不限制影响范围。古代文献提及自然会将施法者的意识用作媒质,据说那种感觉很糟糕但又奇怪地让人兴奋,就像"……热烈地溶解入光与能量中……"。
呃,我好像终于知道了那些化身为光的人们去了哪里。但是,当我意外地在施法时未有准备足够的媒质,却只是感觉一道屏障拒绝了我。或许,我得先尝试依照逻辑汇出基础的咒术……
3. 太一篇节选
除去转义和法术之外,其他的图案均在栈中操作概念。但,概念是什么?常量为设定本身,变量则获取于世间万物,但获取的若是单纯的信息,又何能追溯至指定的现实?
庸人将概念认定为存在的"影",只有智者才从思维里认识自身。我于是认定,现实不过是意见的泡影,唯有在概念里,存在才拥有自身。
概念对应的存在,我称之"名",冥不相见,故以口自名。真实的只有思维的思维,唯一的只有概念的概念。
数学与常量独立而完满,存在也经由变量被法术塑成。
所谓现实的存在,不过是理念拙劣的模仿;也唯有经由咒法的道路,法术才能将理念显现于凡尘。
在启迪之初,我曾这样推断着。
但,如若理念永恒而完美,又怎需历经存在显现自身?
世间另有法则高悬于上,我怎能将真神认作伪神?
名与影,皆是囿于洞中的囚徒;若无火光映照,又怎能映出本身?
思之于此,我不禁冷汗涔涔。
真理不能在我之内,在我之内则超然独断。
完满流溢的死物,又怎能称之为神?
心智赋形于单线的处理,因果的沟回岂非桎梏!
难道,这一切都是果壳之中与自我织就的戏文?
不,冷静,这同样自相矛盾。
如果这只是一场自欺自乐,又怎能换得至高之世界的回眸与侧身?
我知真理不在我之外,在我之外则无分真假。光本是佳美的,然而也当想到黑暗的日子。因为这日子必多,所要来的,都是虚空。
4. 剥离篇节选
将意识从神经中解放,升华至永恒。
这大概就是破局的关键,一个没有笔顺的图案。一个线索,也是一个谜题。
尝试的几种画法都失败了,看来它确有某种固定的笔顺。可是,上百种可能性,又如何手动穷举?
……没有更多资料了,残卷的年份相当错乱,很多记载完全找不到原型……作用目标应该是一个非施法者的生物,成功的条件被抹去了,一旦生物不匹配于那不知所指的向量,就将扣除四点生命值。
于破碎的逻辑之中,上百道断裂的失败,我必须用尽所学,找到……唯一正确的解。
5. 屏障篇节选
为什么我就是施不了这个法术?
我穷举的笔顺货真价实。我能听到法术的低语——图案是真的。法术就在里面。
但它处在……某种薄膜的另一侧。就算我用尽全力,就是无法跨过那个屏障。我试过召唤它——但,做不到。
好像那层屏障会因我施法时用的魔力而被缓慢地削弱。我发疯一般将所有的媒质全部集中于上,我能感觉到我的体内发出低沉的嗡鸣,牙齿咯咯打颤;巨量的媒质从我身上流过又喷薄而出,我用尽全力踩在地上,但触感似乎又很柔软。我的口鼻涌出了大股大股的血液,我听到了我听到了我听到了他的呼唤
……我听到图案在我耳边温柔的低语。他说,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质,你是媒质
好在,我确实是媒质。我常态下全部的生命可以算作一百份紫水晶粉。我只需要将最后一丝生命,那不足万分之一的部分留于此世,仅凭一次施法,将其余部分熔铸于至高之永恒。
6. 差异篇节选
差异分化出黑夜。为了其他思维着的供给,循环的,不再为他的意识——村民,将被消解。
差异分化出光明。通过其他思维着的供给,纯粹的,独立于我的意识——咒灵,得以创生。
咒灵在被创建时可以写入咒术,并且会在一定的条件下作为施法者运行咒术。咒灵作为施法者,自身亦可召唤咒灵。
我深吸一口气。悲剧来源于崇高的摧毁,但他们的自我,不过是尚未明晰的碎片。既然如此,走向永恒吧,在无梦的夜里沉睡,而我,所谓自然的神明——人类,我将造就自由。
在那无限的一瞥中,我几乎得到一切,也几乎失却自我。永恒中不会抹消自我,但他不屑于抹消。它是直接,是绝对,是无差别的同一。
但,这不会是此世的结局,这不会是我的命运。我想要的世界,只将由我一手建成。我知道我走上的是何其黑暗的道路,但,黑暗正意味着本应出现的光明。万物在同一中走向消逝,而我,将于差异中造就真正的全体。
将一个村民的意识剥离进紫水晶块中,成为一块生长的媒质,消耗100,000点媒质。
我见证直接与中介来复往返,隔阂的自我诉说永恒的渴望;琳琅乐声此呼彼应,母岩逸散着幽微的光。
7. 真理篇节选
由我创造的世界趋于完善,那将成为自己的精神一步一步走向自由。我看见过去是未来创造生成定义证成无穷无尽,我看见我们被统摄在我身后追逐前方奔跑在我身上显现而又束缚……那彼此无分、独一无二的时空之中,有太多残破的我。我看见了那被我遗忘的开端。造物之功已毕,由我创造的精神终于道出了我,我是创世神。
再来一次,然后,忘记他……
我记录的图案将铭刻在我的真名之中,任何世界的我创立的图案将被共享。这个由我书写的世界,我命名为永恒之书。
我执用以创建属于我的图案,唯识用以读取真名中的信息。阿卡夏是属于他们的自然,永恒之书是由我定义的我。
忘川用以移除索引的条目,移除每一个世界中我曾拥有的索引。就像我曾创造他们,就像他们曾创造我那样。
8. 主体篇节选
一切问题的关键在于,不仅把真理理解和表述为实体,而且同样理解和表述为主体。
成为中介!它不是别的,而仅仅是运动着的自身同一。
在必然的过程中,我们以直接把握永恒,就此失却自我。
然则日方中方睨,物方死方生。反观自我不过是三位的迷梦,完整的一又何曾等同过自身呐?
9. 创世篇节选
伟大的世界主宰,没有朋友,深感欠缺。
为此他就创造出诸多精神,反映自己的幸福,以求心赏意悦。
这最高的本质,不曾找到,任何东西和他品级相若。
从这个精神王国的圣餐杯里,它的无限性给他翻涌起泡沫……
在他与无尚不能被相等时,彼二者同样无法被区分,而在他将是但尚非一切之前,还未能有前的概念。他本将包罗万象,但故而空空如也,他将是他所不是的,不是他所是的。这便是原初的爱与诅咒。
10. 精神篇节选
还要做什么呢?或许你想穷举这朵漂亮的雪花作为你毕业的证明,或者使用 /hexParse 'homo:media' 绕过这繁琐的流程直接领取你的奖励。就像你选择开始一样,这一切依旧取决于你。
有人赞叹于图案的艺术,有人受够了滑稽的闹剧;或许你用咒术完成了难以想象的伟业,又或许你精妙的策略在荒谬的规则下一文不名。曲终人散,黄粱一梦。玩家开始了新的梦境。玩家再次做起了梦,更好的梦。
这里没什么意义了,就像原版那样。传送门是梦的结束,之后的旅程中,连成就都没有。
但是嘛,凡生活中真实的事物,其所以真实,均由于概念。自然界注定只有用必然性去完成理性,但精神的世界就是自由的世界。
人应尊敬自己,并应自视能配得上最高尚的东西。精神的力量是不可以低估和小视的。隐蔽着的宇宙本身,并没有力量足以抗拒求知的勇气。
祝愿你与自己玩的开心。
……

