TerraBlind
一个 tModLoader(泰拉瑞亚模组加载器)模组:把泰拉瑞亚的感知、寻路、建造、战斗拆成一套可调用的工具,再用这些工具组合出一条从新世界开局到打死肉山(Wall of Flesh)的完整流程。Boss 战由 Jev 驱动,是 Jev 在”实时游戏决策”场景里最有参考价值的公开实例——因为它把”模型负责什么、代码负责什么”划得极其干净。
- 仓库:
github.com/Reisenbug/TerraBlind(MIT) - 演示视频:B 站
BV1Boe26JEh4(Jev 打穿大师模式肉前全 Boss)、BV1PmbP6ZEJc(纯代码 14 分钟通关肉山) - 环境:Terraria 1.4.4.9 + tModLoader + DragonLens
- 项目自述”完全在 AI 辅助下开发”
关键要点
1. 项目定位:一切皆”工具”,主线是手工串的流程
- 项目里”每一样东西,本质上都是工具:寻路、瞄准、使用物品、开箱、放平台、盖房,等等”。
/start是手工把这些工具串起来的一条流程,目标是击败经典难度的肉山。- 两个 milestone,顺序很关键:
- 上一个:“纯代码通关肉山,没有 AI 介入游戏。已完成。”
- 当前:“让模型开打。 boss 战由 Jev 驱动。”
这是理解 Jev 在游戏里角色的关键:“去哪、怎么走、怎么搭桥”全由代码完成,跟模型无关。Jev 只接管”战斗里每一步选哪个动作”这一小段。
2. 两层架构:Jev 出判断,代码出手
| 层 | 谁在干 | 干什么 | 频率 |
|---|---|---|---|
| 决策层 | Jev | 同一份 state,一次并行问五个问题 | 每 200ms(5Hz) |
| 反射层 | 纯代码 | 把意图翻译成按键 | 每帧 |
- Jev 那一次并行提问的五个问题是:九选一的意图 + 五档危险度(Score)+ 要不要冲刺 + 要不要跳。
- 九个意图(动作空间,由人定义):
Keep/Back/Close/Evade/Up/Float/Grapple/Orbit/Dive。 - 反射层负责的具体事项(全部是代码):瞄准、距离、冲刺的双击时序、钩爪落点搜索、跳跃的”松一帧”、意图过期回退。
- 作者总结的分工:“Jev 答判断,代码拥有瞄准、距离、时序和 TTL。“
3. 每个 Boss 的”知识”是一段文字,不是分支代码
- 每个 boss 的背板存在
Jev/Fight/BossBook.cs,形式是一段中文文字:怎么打、场地什么样、禁用哪几个意图、保持几格。 - “加一个 boss 通常只是加一条文字条目。“目前有七条:克苏鲁之眼、史莱姆王、克苏鲁之脑、世界吞噬者、骷髅王、蜂王、鹿角怪;另有肉山与恶鬼两条距离规则。
- 可证伪设计:
/bossbook可以整个关掉背板,只留场地和通用字段,“用来验知识到底值多少”。 - 录制在大师模式下跑的。
4. 降级与容错
- 需要一个 TypeSafe API key,读取顺序:模组配置界面 → 仓库根目录
.env→ 环境变量TYPESAFE_API_KEY。 - “没有 key 时战斗层退回保守的 baseline,不影响主线流程。“
5. 主线流程(纯代码部分)
在种子 1.1.2.38154567 上稳定跑通:/start → 建造速通 4 人 NPC 房屋 → 前往丛林并尽量从 main entrance 下地狱 → 地狱选址 → 搭桥(190 格)→ 盖 NPC 单间 → 引入爆破专家买雷管 → 引入向导并捅下岩浆 → 雷管定点爆破肉山。
- 全程
/start到击败肉山 14 分 15 秒(三倍速下)。 - “其他种子有的能跑通,有的还会卡……’所有种子都通’不是这个项目的当前目标。”
- 为避开复杂机制做的原版改动:常驻鱼鳃/光芒、岩浆上方接触格转方块、新玩家自带无限木材 + 4 火把、捅向导时加长挖掘范围、DragonLens 相关修改。
- 依赖 DragonLens:关闭刷怪、无敌、倍速、坐标显示(“当前 milestone 不处理战斗生存,只求全程动作可行”)。
6. 代码结构与工程约束
- 159 个
.cs文件,按职责分目录:Core/(判据)、Perception/(眼睛:状态快照、物理模拟器、差分)、Nav/(寻路)、Actions/(原语)、Build/(建造)、Flow/(流程编排)、Jev/(模型层:走位意图、boss 背板、威胁扫描、请求与降级、HUD 与日志环)、Infra/、Debug/。 - 一条硬规则:“‘卡住’必须在结构上不可能”——每个原语失败时都要交出可被上层处理的失败现场(
Blocker),而不是静默return;由check.sh强制。 - HTTP 服务起在
http://127.0.0.1:17878,152 个端点;主线只用POST /start_run、POST /hell_run、GET /state等少数几个。 - 注意:地址一律用
127.0.0.1,不要用localhost(会走::1,前缀匹配不上)。
7. 为 AI 辅助开发专门做的设计(对写代码的人也有参考价值)
| 环节 | 做法 |
|---|---|
| 编译自验 | ./check.sh 只做类型检查不打包,约 1 秒,游戏开着也能跑 |
| 定位自验 | 三层日志 + 一条规矩:每个判断都要打出它依据的那个数,不只打结论 |
| 机器下限 | stuck_contract.sh 检查原语是否交出失败现场;dup.sh 查同一件事有没有两份实现 |
| 写码约束 | .claude/hooks/ 两条:注释块不许超长、标点必须 ASCII |
- 作者的话点出了要害:“真正花时间的是判断哪个环节出了问题。上面这套的意义就是把’读日志找原因’这一步也变成 AI 能独立做完的事。“
重要引用(英文原文 + 中文翻译)
“Everything in TerraBlind is a tool: pathfinding, aiming, using items, opening chests, placing platforms, building houses, and so on.” TerraBlind 里的每一样东西,本质上都是工具:寻路、瞄准、使用物品、开箱、放平台、盖房,等等。
“Previous milestone: beat the Wall of Flesh with code only, no AI. Done.” 上一个 milestone:纯代码通关肉山,没有 AI 介入游戏。已完成。
“Jev answers every 200ms (5Hz). One state, five questions in parallel: one of nine intents (
Keep/Back/Close/Evade/Up/Float/Grapple/Orbit/Dive), a five-level danger score, whether to dash, whether to jump.” Jev 每 200ms 答一次(5Hz)。同一份 state 一次问五个并行问题:九选一的意图、五档危险度、要不要冲刺、要不要跳。
“A reflex layer turns that into keystrokes every frame: aiming, distance, the double-tap timing for dashes, hook anchor search, the one-frame release a jump needs, intent expiry. All code.” 反射层每帧把它翻译成按键:瞄准、距离、双击时序、钩爪落点搜索、跳跃需要的”松一帧”、意图过期。全部是代码。
“Jev answers judgments; the code owns aiming, distance, timing and TTL.” Jev 给出判断;瞄准、距离、时序和有效期全归代码。
“Each boss’s playbook is a paragraph of text (
Jev/Fight/BossBook.cs), not a branch: how it fights, what the arena is like, which intents are banned, how many tiles to keep. Adding a boss is usually just adding a text entry.” 每个 boss 的背板是一段文字(Jev/Fight/BossBook.cs),不是分支:怎么打、场地什么样、禁用哪几个意图、保持几格。加一个 boss 通常只是加一条文字条目。
“
/bossbookswitches the playbooks off entirely, leaving only the arena and the generic fields, to measure what the knowledge is actually worth.”/bossbook可以整个关掉背板,只留场地和通用字段,用来验知识到底值多少。
“Without a key the combat layer falls back to a conservative baseline and the main pipeline is unaffected.” 没有 key 时战斗层退回保守的 baseline,不影响主线流程。
“One hard rule: getting stuck must be structurally impossible.” 一条硬规则:“卡住”必须在结构上不可能。
“Every significant decision logs the number it was based on, not just the verdict. Otherwise diagnosis is guesswork.” 日志里的关键判断都会打出当时用来判断的那个数,而不只是结论。不然出问题只能靠猜。
与 Jev 官方文档的对应关系
| TerraBlind 的做法 | 对应的官方结论 |
|---|---|
把游戏状态转成结构化文字再喂进去(Perception/) | 官方文档:Jev 仅接受文本输入;DOOM 官方 demo 也声明”输入是结构化状态,不是画面” |
| 瞄准、距离、双击时序、跳跃时序全放代码 | 官方缺陷清单:Jev 数学和数字不行、日期时间不可靠、“能算的别交给模型” |
| 只让 Jev 出”意图”这个纯语义判断 | 官方:“把宽泛判断拆成原子问题,在代码里组合” |
| 没 key 时退回保守 baseline | 官方:置信度低时不行动、可回退到更强模型或人工 |
/bossbook 关掉背板测”知识值多少” | 官方:阈值与效果必须用自己的数据验证,不能拍脑袋 |