返回创作札记

产品札记

为什么 HuanYe 把公开阅读与游玩分开

同一部互动小说需要两种诚实的入口:公开阅读交付可核验的发布正文,游玩界面承接选择、状态与运行时回应。

发布作者幻夜更新4 分钟阅读

门口摆着两张桌

一张桌上是摊开的纸页,油墨味还没散,访客可以站着读完几段;另一张桌上有筹码、记录纸和一支会不断改写局面的铅笔。互动小说同时需要这两张桌。若只留下游玩入口,陌生读者在建立身份、载入状态以前看不到作品究竟写得怎样;若只留下文章,选择造成的距离、代价与回声又会被抹平。HuanYe 因而把“公开阅读”和“游玩”做成两个相连但职责不同的表面。

这里的分开不是把同一段宣传文案复制两次。公开阅读回答的是:这部已发布作品有哪些可直接阅读的正文,语言、节奏与题材是否适合我?游玩回答的是:我按下这个选择以后,人物关系、物品、属性、路线和下一幕怎样改变?前者必须让匿名访客获得完整判断材料,后者必须拥有可以持续写入的参与者状态。

公开阅读交付的是发布快照

公开路由向后端请求 GET /api/stories/{id}/read,并明确携带 locale。它读取 published_content,而不是作者仍在修改的草稿;服务器只选出带 scene_text 的 authored 或 ending 节点,清掉运行时标记,再把章节、标题、正文和选择文字交给服务端页面。访客不必登录,正文已经在首份 HTML 里,而不是等浏览器执行脚本后才出现。

这个表面也有边界。买断作品只公开免费章节;海龟汤和审讯故事的 ending 节点会被排除,避免阅读页把谜底先揭开。页面展示选择文字,是为了让人看见分支的存在,并不会在这里执行效果、结算背包或写入进度。换句话说,阅读页证明作品确实有正文,却不伪装成一场已经开始的游戏。

语言错误也不能用回退掩盖。明确请求英文时,后端只有在公开字段与节点翻译完整后才返回英文载荷;覆盖不全就是 404,而不是把中文段落塞到 /en/。相反,后端断线或返回其他错误会让页面报错,不被伪装成“故事不存在”。这种差别很细,却决定了访客、爬虫和维护者看到的是不是同一个出版事实。

游玩保存的是一次具体经历

进入 /stories/[id]/play 后,页面先尝试读取当前预览,再由 start 建立或恢复 conversation。选择不再是印在纸边的箭头:它可以通过统一的 effect 结构增加属性、放入物品、设置变量、跳转节点;当前 node_key、玩家状态快照与进度随后成为下一回合的输入。注册用户如此,系统来宾身份也要有自己的限额与会话,否则两个人按下同一个按钮会共用一份记忆。

运行时 AI 也只属于这一层,而且不是每次点击都调用。代码把可直接结算的静态转场列为 free path:先应用作者写定的选择效果,再进入目标节点,不产生 AI 回合。自由输入需要主持回应时,模型才在故事上下文、工具和揭示边界内接话。于是“预写正文”和“临场回应”能在同一部作品里共存,读者也能辨认哪部分是稳定出版物,哪部分来自这次游玩。

全部公开,不等于全部收录或全部投广告

最容易混淆的是最后这一层。HuanYe 把 published 且 is_public=true 视为公开可见;搜索索引资格按页面与语言另算,广告资格又是索引资格的更小子集。一部故事可以继续让访客阅读,同时因为翻译不完整、正文不足、内容分级或审核记录缺失而保持 noindex、no-ad。这不是把内容藏给审核者看,而是让访问权与商业判断各自说清楚。

系统会给最终阅读载荷生成指纹。记录缺失、文字改变、规则版本不符,index_eligible 与 ad_eligible 都按失败关闭;旧批准不会悄悄转移到新正文。这个取舍比“一键全开”慢一点,却更诚实:公开负责让作品被看见,索引负责确认页面值得被搜索,广告负责确认同一份具体内容适合商业展示。三件事有关联,不能用一个开关代替。

因此这次最合理的选择不是把所有开关同时拨到“是”,而是先让作品保持可访问,把正在补证据、补翻译或补署名的页面留在 noindex、no-ad。待具体指纹完成检查,再分别开放发现与商业层。读者从一开始就能读到真实正文,后续资格变化也不需要改写作品身份或制造另一份审核专用页面。

为什么 HuanYe 把公开阅读与游玩分开 - HuanYe 创作札记