在 Twine 的 Harlowe 叙事引擎中,使用 `(link:)` 宏创建的链接会在点击后自动从页面消失;若希望实现多次触发同一交互(例如反复弹出提示信息),则应改用 `(link-rerun:)` 宏——该宏会保留链接并重新执行其内部内容。
这个问题在 Twine/Harlowe 的交互式叙事创作中其实相当常见。你可能会发现,Harlowe 默认的 `(link:)` 宏本质上是一个“一次性”交互:用户一旦点击,链接所在的文本节点就会被替换,通常直接消失得无影无踪。很多新手的第一反应是“这算不算 Bug”?其实并非如此,这恰恰是它的设计初衷——`(link:)` 的语义就是“跳转或触发一次动作后退出当前上下文”,用完即撤,干净利落。
但问题也随之而来:许多实际场景需要的是“持久可点击的按钮式链接”。比如玩家反复检查某件物品,或者重复触发某段对话,再或者你在调试测试时希望某个交互始终可用。这时如果继续使用 `(link:)`,链接点一次就没了,体验会非常不流畅。该怎么办?别担心,Harlowe 其实早已内置了另一个宏——`(link-rerun:)`,它的语义正好与这类需求匹配:点击后链接保留,内容重新执行。
✅ 正确写法(链接常驻,可无限次点击):
Thing (link-rerun: "Look at")[(alert: ["It's a thing"], "Sure.")]
⚠️ 注意事项:
- `(link-rerun:)` 不会刷新整个 passage,它只重新运行内部的糖语法,比如 `(alert:)`、`(set:)`、`(if:)` 等。因此它特别适合轻量级、无副作用的交互,不要指望它承担复杂任务。
- 如果链接内部涉及状态变更,比如一个计数器,逻辑需要写清楚。举个例子:
(set: $clicks to it + 1)You've clicked this $(clicks) time(s). (link-rerun: "Click again")[...]
- 注意,避免在 `(link-rerun:)` 中执行破坏性操作,例如 `(goto:)` 或清空变量。这个宏虽然方便,但不像看起来那么皮实,不当使用可能引发意外行为。
- 千万不要把 `(link-goto:)`(跳转到另一 passage,原链接保留)和 `(link-rerun:)`(留在当前 passage,重执行内容)搞混。虽然名字相似,但用途截然不同。
总结一下:当你需要实现“点击后响应,响应后还能再点”的交互时,`(link-rerun:)` 就是 Harlowe 给出的标准解决方案。理解这几个链接宏的语义差异——`link` 是一次性触发,`link-rerun` 是可重入的持久链接,`link-goto` 是导航保留——这才是构建稳定、可维护的 Twine 故事的核心基础。
