真之符文 - 强力事件修补器

真之符文 - 强力事件修补器

一款强大的星露谷物语事件修补器。每个事件只需放入一个JSON文件,即可获得分支选择、子事件、片段、条件步骤、结果追踪以及一个简单易用的调试命令。

模组工具

真符文:事件——强力事件修补器

分支式。结构化。可编撰。用JSON实现自定义爱心事件。

场地

每个事件放置一个JSON文件,即可获得分支选择、子事件、片段、条件步骤和结果追踪——完全无需编写一行C#代码,也无需在原始事件命令字符串中数正斜杠。 True Rune: Events 是《呼吸山谷》所基于的框架,经过提取、通用化,随时可供您填充内容。作者以应有的方式编写爱心事件:一个文件、命名字段、命名选择、命名结果。

与内容补丁(Content Patcher)协同工作

两个模组都编辑 Data/Events/*,但作用于不同层级。Content Patcher 提供原始指令字符串控制。True Rune: Events 为你提供结构化创作领域特定语言(DSL)。你可以同时使用两者——TRE 注入的事件,其前置条件星露谷物语会像其他任何事件一样进行精确评估。

TRE 在 Content Patcher 的 EditData Data/Events/ 基础上新增的功能*

  • **逐步JSON,而非斜杠分隔的命令混合体。**每个步骤都是一个具有命名字段的独立对象。不包含计数分隔符。
  • 分支是一级概念。 quick_question 搭配 answers 与 branches 数组。编译器会为您生成正确的 quickQuestion #a#b(break)cmd1\\cmd2(break)… 代码。
  • **自动抑制的子事件。**声明 is_sub_event: true 后,框架会在加载存档时预先将其标记为已触发,从而避免星露谷物语自动触发它们——只能通过父分支中的 switch_event 来访问。
  • 内置结果追踪功能。 为每个结果声明一个 mail_flag;观察者轮询 mailReceived 并自动将事件标记为完成。无需手动记账。
  • 可重用片段。 将一系列步骤抽取为命名块,并用 { "op": "include", "fragment": "<name>" } 引用它。减少多分支事件中的重复内容。
  • 任何步骤上的when子句。 基于玩家历史跳过整个步骤的编译时标志谓词(全部 / 任意 / 无)。
  • 季节与日期的门控机制。 为日期窗口事件的前提条件添加季节和日期(例如:春季第1-23天,花舞节之前)。
  • 关系 & 花舞操作 set_relationship 将NPC翻转为约会/订婚/已婚状态,而 set_dance_partner 直接通过JSON指派一名节日舞伴——无需递交花束或任何物品。
  • emote_by_flag 步骤. 根据先前选择挑选一个表情,无需编写C#选择器。
  • 极速事件调试模块。 添加warp_x/warp_y和场景地图,即可免费获得rune_event_run <id> <scenario>——这正是内容作者真正想要的测试循环功能。
  • 自验证。 启动时捕获的数字ID冲突。加载时警告未知的邮件标志引用。
  • AI友好型。 完整编写指南包含在zip文件中——将docs/EVENT_AUTHORING.md连同你的大纲一起粘贴到Claude/ChatGPT中,即可获得可用的JSON反馈。

混凝土对比 — CP与TRE中的相同分支事件

内容补丁方法:使用每个事件一个巨大的前置条件→脚本字符串来编辑 Data/Events/Town

"行动": "编辑数据"
"Target": "Data/Events/Town"
"条目": {
"9900004/f 罗宾 1500/e 9900003": "spring_day_ambient/45 65 true/farmer 45 68 0 罗宾 45 66 2 skippable/pause 500/speak 罗宾 \"开场白。$h\"/quickQuestion #当然!我很乐意。#抱歉,今晚很忙。(中断)addMailReceived MYPACK_LH04_accept\\friendship 罗宾 50\\end(中断)addMailReceived MYPACK_LH04_decline\\friendship 罗宾 10\\end"

难点:

  • 标题在哪里结束,正文从哪里开始?(计算正斜杠数量。)
  • 在中间添加一个新选项?重新计算斜杠位置,正确转义斜杠与反斜杠分隔符,然后祈祷。
  • 仅在玩家设置了某个标志时,有条件地额外暂停一秒?星露谷的原版前置条件系统无法内联实现——你需要创建第二个事件条目,并设置重叠的前置条件。
  • 通过switchEvent链入一个子事件?星露谷物语随后会也尝试在其自身位置自动触发该子事件。你需要一个独立的模组来标记它为已触发。
  • 不在不重载存档的情况下测试?不行——星露谷物语会在进入位置时评估字典,事件触发后你必须手动清除邮件标记和已见事件记录。

TRE中的相同事件:

"id": "LH04"
"title": "罗宾邀请玩家回家"
"location": "小镇"
"category": "linear"
"debug": { "warp_x": 45, "warp_y": 68 },
"outcomes": [
{ "mail_flag": "MYPACK_LH04_accept",  "description": "接受了罗宾的邀请" }
{ "mail_flag": "MYPACK_LH04_decline", "description": "礼貌地拒绝" }
]
"text_content": {
"LH04": [
{ "type": "lines", "sort_order": 0, "speaker": "罗宾", "emotion": "$h", "text": "嘿 @,想来我家吃晚饭吗?" }
{ "type": "choices", "sort_order": 0, "choice_id": "yes", "text": "当然!我很乐意。" }
{ "type": "choices", "sort_order": 1, "choice_id": "no",  "text": "抱歉,今晚没空。" }
]
}
"变体": [
{
"key": "default",
"section": "LH04",
"precondition": { "friendship_points": 1500, "npc_name": "Robin", "required_completed_event_ids": ["LH03"] },
"header":{
"music": "spring_day_ambient"
"viewport": { "x": 45, "y": 65, "clamp": true },
"farmer": { "x": 45, "y": 68, "facing": "up" },
"actors":   [ { "name": "Robin", "x": 45, "y": 66, "facing": "down" } ]
},
"步骤": [
{ "op": "pause", "ms": 500 },
{ "op": "speak", "sort_order": 0 }
{ "op": "quick_question",
"answers": [ { "sort_order": 0 }, { "sort_order": 1 } ],
"分支": [
[ { "op": "add_mail", "flag": "MYPACK_LH04_accept"  }, { "op": "friendship", "npc": "Robin", "delta": 50 }, { "op": "end" } ],
[ { "op": "add_mail", "flag": "MYPACK_LH04_decline" }, { "op": "friendship", "npc": "Robin", "delta": 10 }, { "op": "end" } ]
]
}
]
]

你从中获得:

  • 像故事一样从上到下阅读。 设置 → 标题 → 步骤 → 分支。
  • **每个步骤都可以独立编辑。**插入新的暂停?将一个对象拖入步骤数组。完成。
  • **分支结果仅需声明一次,即可随处引用。**在结果中添加另一个结果,观察者会自动获取它。
  • 条件性步骤包含。 将 "when": { "all": ["MYPACK_RELATIONSHIP_HOT"] } 添加到任何步骤中,当标志未设置时,框架会跳过该步骤——无需第二个事件条目。
  • 内置测试命令。 rune_event_run LH04 可将你传送到触发点,并通过一条控制台命令启动事件,无需重新加载存档。

安装后即可立即使用

这个框架自带一个微小的冒烟测试事件(SMOKE01),用于罗宾在镇上的场景——将模组放入,将罗宾好感度提升到1心,下次你在镇上走过她身边时,她会确认真符文:事件已正确连接。

作者快速入门

你的内容包是一个标准的SMAPI内容包:

MyEventPack/
├── manifest.json   (内容包用于: "Riou.TrueRune.Events")
└── TrueRune/
└── events/
├── linear/
│   └── LH04.json
└── interlude/
    └── IN02.json

TrueRune/ 伞式结构将所有 True Rune 工具包子系统收纳于同一文件夹内。如果你的模组还附带 TrueRune/dialogue/,对话框架会通过工具包的交叉发现机制自动识别这些文件——你只需声明一次 ContentPackFor。

manifest.json:

"Name": "我的活动包"
"作者": "你"
"版本": "1.0.0",
"描述": "为罗宾添加新的心动事件。"
"UniqueID": "You.MyEventPack",
"ContentPackFor": {
"UniqueID": "Riou.TrueRune.Events",
"MinimumVersion": "1.0.0"
}
}

将文件夹拖入 Stardew Valley/Mods/ → 启动 → 走到触发位置。这就是全部流程。

架构参考(顶层)

  • id — 事件ID(例如LH04)
  • 标题 — 人类标签
  • 位置 — 星露谷物语位置资源名称(城镇、种子店、海滩、农场…)
  • 类别 — 线性 / 次要 / 随机 / 约会 / 婚后 / 季节 / 心理战斗 / 幕间
  • owner_npc — 该事件所属的NPC;驱动每个NPC的完全沉浸+基于事件的关系链,并在前置条件通过friendship_points而未指定npc_name时提供心门NPC。若省略则从第一个变体推断得出——在多NPC场景中请明确设置。
  • numeric_id_base — 此事件的数字ID基数的可选覆盖(避免冲突)
  • 自动注入 — 对于过场/手动触发事件设为false
  • 调试 — 启用 rune_event_run 调试命令(传送坐标 + 场景)
  • 结果 — 邮件引擎监视的标记,用于标记事件完成
  • 文本内容 — 按区块索引的嵌入对话(台词、选项、独白)
  • 片段 — 可重复使用的命名步骤序列
  • 分支路径 — 分支路线(例如 默认 + 子事件变体)

模式参考(步骤操作)

  • 暂停 — 等待N毫秒
  • 移动 / 面向 / 扭曲 / 跳跃 — 移动一个角色
  • emote / emote_by_flag — 显示表情气泡(第二种变体根据标记选择)
  • 说话 / 独白 / 头顶文字 — 显示来自文本内容的对话
  • 快速问答 — 分支选择(答案 + 分支数组)
  • 友谊 / 添加邮件 — 状态变化
  • set_relationship / set_dance_partner — 直接设定好感度状态(约会/订婚/…)或花舞搭档,无需花束/道具
  • 已触发事件 / 切换事件 — 链接到另一个事件
  • change_location / global_fade / global_fade_to_clear — 场景过渡
  • animate / play_sound — 动画 + 音效
  • 结束 / 结束位置 / 结束对话 — 关闭事件
  • raw — 逐字插入星露谷事件命令(应急出口)
  • include — 内联一个命名片段

在发布包中的samples/Sample-RobinFarmVisitPack/路径下,有一个完整的示例,涵盖了分支、片段和结局船舶。完整的模式文档位于压缩包内的docs/EVENT_AUTHORING.md中。

安装

  1. 安装 SMAPI 4.0 及以上版本
  2. 推荐: 通用模组配置菜单,用于游戏内设置页面
  3. 将解压后的文件夹放入星露谷物语/Mods/
  4. 安装任何需要此框架的内容包

控制台命令(前缀 rune_)

· rune_event_run <事件ID> [场景] — 强制触发一个事件 · rune_event_unsee <eventId> — 将事件标记为未看到,以便可以再次触发 · rune_event_eligible — 显示每个已注册事件的资格状态 · rune_event_list — 列出按所属内容包分组的每个已注册事件 · rune_event_reload — 重新扫描磁盘上的每个JSON文件并重新构建注册表,无需重启SMAPI

安装真实符文:模组工具包以获取这些指令以及通用肖像/列表/转储助手。如需1:1状态设置器,请使用原版debug seenMail / debug question / debug seenEvent。未安装工具包时,此框架不会注册任何控制台指令。

在 SMAPI 控制台中输入 help rune_<名称> 以查看用法。

C# API

var api = Helper.ModRegistry.GetApi<IEventForgeApi>("Riou.TrueRune.Events");
// 注册一个全新的步骤操作,以便 JSON 作者可以编写 { "op": "screen_flash" }
api.RegisterStepCompiler(new ScreenFlashCompiler());
// 声明一个数字ID前缀,以确保你的内容包的事件永远不会冲突
api.RegisterNumericIdPrefix("FX", 9930000);
// 强制触发来自你自己模组的事件
api.TriggerEvent("LH04", scenario: "tour");

兼容性与权限

SMAPI 4.0+ / Stardew Valley 1.6+。可与 Content Patcher 事件编辑和自定义NPC框架叠加使用。MIT 许可证 —— 无需询问即可作为依赖使用,可自由分支,欢迎翻译。

真实符文工具包的一部分

  • 真纹章:对话导演 — 运行时NPC对话规则引擎,包含优先级、轮换、最大使用次数限制以及跨NPC心之门
  • 真符文:模组工具包 — 角色立绘查看器 + NPC枚举 + 标志操作
  • 真符文:日程导演(计划中)——条件NPC日程