当前位置: 首页 > news >正文

小说游玩辅助功能开发

在完成StoryVerse的游玩模式开发后,我主要围绕游玩模式之外、用于提升用户体验的辅助功能做补充。系统游玩模式的核心闭环是上传小说、选择情节节点、进入游玩页面,然后由后台游戏循环持续推动角色行动。这个闭环可以证明“基于小说设定进行角色扮演”这件事能跑起来,但实际使用时还是会有一个明显问题:用户如果对小说内容不够熟,或者想在游玩前先了解角色和背景,只靠开始游戏按钮是不够的。因此这一阶段我把开发重点放在小说原作阅读、角色设定、角色对话、角色关系图和历史游戏回顾几个模块上,让用户在进入和离开一局游戏时都有地方可以查阅、理解和复盘。

一、原作阅读模块

我首先做的是小说原作阅读,以小说阅读器的形式,供用户了解小说原作内容。小说上传时,原文会在后端本地目录中,数据库的 novel 表记录raw_file_uri以维护文件路径,所以我在 Spring Boot 中新增了ReadingControllerReadingService,由后端根据小说 id 查询数据库,再通过文件路径解析器找到真实文本文件。

这个模块我比较在意的一点是不能一次性把整本小说都返回给前端。小说原文通常很长,如果直接下发全文,页面首屏加载、内存占用和滚动体验都会变差。最后我采用固定字数分页的方式,默认每页 3500 字,并限制最大 pageSize,前端只根据页码请求当前页内容。后端核心逻辑大致是这样:

intnormalizedPageSize=normalizePageSize(pageSize);inttotalChars=content.length();inttotalPages=Math.max(1,(int)Math.ceil((double)totalChars/normalizedPageSize));intnormalizedPage=normalizePage(page,totalPages);intstart=Math.min((normalizedPage-1)*normalizedPageSize,totalChars);intend=Math.min(start+normalizedPageSize,totalChars);StringpageContent=content.substring(start,end);

这里没有按章节切分,是因为上传进来的 txt 来源不统一,章节标题格式也不稳定。有的小说是“第几章”,有的可能是卷名、空行、特殊符号混用,如果我在这个阶段强行写章节识别,反而会引入很多不可靠规则。固定字数分页虽然不够文学化,但稳定、可解释,而且和当前项目阶段更匹配。

前端阅读页我做成了一个比较独立的页面,路由是/reading/:novelId,但仍然保留导航栏,这样它在体验上属于“小说资料页”,而不是沉浸式游玩页。页面中间展示原文,底部提供上一页、下一页和页码跳转,右侧提供亮色/暗色主题、字体和字号设置。我还用localStorage记录每部小说上次读到的页码,避免用户每次返回都从第一页开始。这一点没有改数据库,因为当前系统本身是伪用户逻辑,小说和游戏记录都没有真正按用户隔离,如果为了阅读进度新增用户维度表,和系统现阶段的数据设计不一致。

二、角色设定与角色对话

完成阅读器之后,我继续做角色设定模块。这个模块的入口放在首页小说卡片上,和“开始游玩”“阅读原作”并列。我的想法是,用户在进入一局游戏前,最好能先看到这部小说中有哪些关键角色、每个角色大概是什么设定,这样选择扮演角色时不会只看到一个名字。

角色设定数据没有直接从 MySQL 的character_profile表取,而是走 FastAPI 查询 Qdrant 中的novel_knowledge集合。这个选择主要是因为系统的小说知识库本来就把世界观、角色设定、原作文本统一放在向量数据库里,角色设定 point 的 payload 中有noveltypecharactertext等字段。Spring Boot 负责接收前端的小说 id,查 novel 表得到小说名,再把小说名转发给 FastAPI;FastAPI 则用noveltype=character两个条件过滤 Qdrant point,最后返回角色名和设定文本。

这一层转发看起来多了一步,但它让职责更清楚:Spring Boot 仍然是业务后端,掌握小说 id、路由和返回给前端的数据结构;FastAPI 负责模型能力层和知识库访问。尤其是 Qdrant 只在 FastAPI 侧操作,后端不用同时维护 MySQL 和向量数据库两套访问逻辑,后续修改知识库结构时也更集中。

在角色设定页上,我用卡片宫格展示角色名和设定文本,每张卡片提供“与该角色对话”按钮,页面顶部提供“查看角色关系图”按钮。与角色对话页是一个单独的聊天页面,前端进入时携带小说 id 和角色名,后端先初始化会话,再由 FastAPI 根据小说名和角色名查询该角色设定,并构造提示词调用大模型。这里我没有把所有聊天上下文都落库,而是在 FastAPI 运行时用一个conversation_id管理会话消息,因为这个功能目前更像辅助体验,不是核心游戏记录。

对话提示词的设计重点是“只扮演该角色”。我在提示词里放入小说名、角色名、角色设定和最近的历史对话,然后约束模型不要暴露系统身份,不要替用户说话,也不要脱离角色认知边界。这样做的原因是角色对话不是普通问答,用户点进“史强”或“叶文洁”,期待的是和这个角色交流,而不是让模型站在百科视角解释人物。

三、角色关系图

角色关系图是角色设定模块的延伸。单独看卡片时,用户能知道每个角色是谁,但不一定能快速理解人物之间的关系。于是我新增了角色关系图页面,由 FastAPI 先复用角色设定查询结果,再调用大模型把角色设定整理成节点和边。节点代表角色,边代表关系,前端用 SVG 渲染成可视化关系图。

这个模块中我遇到的主要问题是大模型输出不稳定。关系图数据必须是结构化 JSON,但模型有时会在 JSON 外面加说明文字,或者创造角色设定中没有出现的新名字。为了解决这个问题,我在 FastAPI 侧做了三层处理。第一层是在提示词中明确要求只输出 JSON,并列出允许使用的角色名;第二层是在解析时尝试从模型输出中提取 JSON 对象;第三层是在规范化阶段过滤掉不在允许角色集合中的节点和边,并补齐缺失节点。

关系图生成还有一个兜底策略。如果模型调用失败,或者角色数量太少,后端不会直接让页面报错,而是返回一个基础图结构:所有角色作为节点,关系暂时标为“关联”。这个结果不如模型分析精细,但至少保证页面能展示,用户不会因为一次模型失败就完全失去功能入口。

前端关系图没有引入额外图谱库,而是自己用 SVG 加一个简单力导向布局来处理节点位置。我这样做主要是为了控制页面风格和交互细节。图中的节点可以拖拽,边用曲线连接,关系名称显示在边附近。为了让图一开始不要太乱,我根据节点度数对角色排序,让关系更多的角色更靠近中心,再通过斥力和弹簧力不断调整位置。这个实现没有追求复杂算法,但已经能让角色关系从文字列表变成比较直观的结构。

四、历史游戏回顾

最后一部分是历史游戏回顾。游玩模式本身会不断产生游戏会话、世界状态和事件日志,如果这些数据只存在数据库里,用户结束游戏后就很难重新理解自己玩过什么。因此我做了历史游戏回顾页面,把game_session中的记录展示成表格,字段包括小说标题、开始时间和场景信息,并为每条记录提供“查看情节推演历史”的入口。

这个模块的后端实现横跨了几张表。GameReviewService先查游戏会话,再根据novel_id查小说标题,根据session_idworld_state里的场景状态。场景状态在数据库里是 JSON,不能直接丢给前端,所以我把它反序列化成WorldStateDTO.SceneState,再拼成自然语言,例如当前场景、地点、时间、天气。这样表格里显示的是用户能读懂的场景描述,而不是内部字段。

情节推演历史则进一步使用event_log。事件日志里有角色 id、行为类型、内容、目标等字段,这些字段适合系统处理,但不适合用户阅读。我在后端先根据当前世界状态中的角色信息补出角色名,再把事件转换成EventDTO发送给 FastAPI。FastAPI 会构造提示词,让大模型把这些事件整理成 2 到 5 个自然段的剧情回顾,并明确禁止输出speakmoveplayer_action这类内部字段。

我也给情节回顾做了降级处理。如果模型生成失败,或者返回内容不符合要求,Spring Boot 会退回到本地事件文本转换,把每条事件用比较自然的中文句子展示出来。例如speak会转成“某角色对某目标说……”,observe会转成“某角色观察到……”。这样做的好处是,模型生成可以提升可读性,但功能本身不完全依赖模型成功。

五、开发过程中的思考

这一阶段的辅助功能开发让我更清楚地意识到,StoryVerse 不是只要有一个能运行的游玩页面就够了。小说角色扮演系统需要很多“游戏前”和“游戏后”的信息支撑:游戏前,用户需要读原作、看角色设定、理解人物关系;游戏后,用户需要回顾自己经历过的情节,知道这局游戏留下了什么。辅助功能不直接推进游戏循环,但会影响用户是否愿意进入游戏、是否能理解角色行动、是否能在结束后继续沉浸。

技术实现上,我尽量没有破坏原有的三端分工。Vue 负责页面组织和交互,Spring Boot 负责业务路由、数据库读取和数据整形,FastAPI 负责知识库查询与大模型生成。比较容易出错的地方,我都尽量加了边界处理,比如阅读页规范页码,角色关系图过滤非法节点,情节回顾保留本地兜底文本。这样功能虽然是辅助模块,但不会因为模型输出波动或数据不完整就让整个页面不可用。

这部分开发中我也使用了 AI 辅助编码,主要让它根据已有接口设计生成前端页面骨架、Spring Boot 控制器和部分样式代码。我的提示词大致是:基于 StoryVerse 现有 Vue + Spring Boot + FastAPI 架构,实现小说原作阅读、角色设定展示、角色对话、角色关系图和历史游戏回顾,要求保持导航栏逻辑和现有接口风格,不修改游玩模式主流程。生成之后我没有直接照搬,而是逐个检查接口路径、字段命名和异常处理,尤其是角色关系图 JSON 解析、历史回顾兜底、阅读分页这些地方,都是结合项目已有数据结构重新调整过的。对我来说,AI 在这部分更像是帮我快速铺开重复代码,而真正决定功能边界和系统稳定性的,还是对项目结构和业务流程的理解。

http://www.zskr.cn/news/1494343.html

相关文章:

  • 嵌入式MCU模拟外设设计:从K51振荡器与ADC规格到实战避坑指南
  • 首岸热销背后的港漂置业逻辑 - 博客湾
  • 终极指南:3步永久解锁Cursor AI Pro完整功能,告别试用限制
  • PPPwn完整指南:利用PPPoE协议实现PS4内核远程代码执行的终极方法
  • 从数据手册到可靠设计:深度解析Kinetis K65电气特性与低功耗实战
  • 上海防水堵漏公司哪家靠谱?2026年实测评测告诉你答案 - 资讯纵览
  • 国内主流仓储笼厂家实测排行:合规性与适配性对比 - 起跑123
  • Facebook广告审核不通过的原因有哪些?7个常见问题解析(2026)
  • 石家庄黄金市场观察与回收策略 - 润富黄金回收
  • 乘行业变革之风,以品类与科技破局 米兰软装构筑一线品牌核心竞争力 - 资讯纵览
  • CH55xduino终极指南:5分钟搞定低成本USB微控制器开发
  • 企微 RPA 接口开放:无需官方权限,外部群自由操作
  • 免费在线去水印工具推荐: 实测哪些工具软件好用?在线怎么去掉水印? - 工具软件使用方法推荐
  • 多维聚合实战:维度建模、度量聚合与数据变形链路
  • 湖州黄金变现全攻略:六月金价高位这样卖最划算 - 润富黄金回收
  • LPC214x微控制器数据手册实战解析:从电气特性到PCB布局的嵌入式设计指南
  • 芜湖专业除甲醛公司哪家效果好 - GrowthUME
  • 世界杯哨响!错过预售的 TikTok 卖家,靠这几类“硬通货”还能翻盘?
  • Windows硬件指纹伪装终极指南:内核级设备标识修改技术深度解析
  • MAA明日方舟助手:解放双手的全自动游戏辅助工具完全指南
  • 合泰BH66F2660-B LQFP48体脂秤专用单片机产品介绍
  • 通达信缠论插件终极指南:3分钟实现专业级技术分析自动化
  • 基于OpenPose的太极拳动作识别实战包(含GUI操作界面、预训练模型与标注数据集)
  • 暗黑破坏神2存档编辑器终极指南:5分钟打造完美角色
  • Android 线程池总结
  • 东莞专业的盲盒卡牌生产厂家怎么选?掌握这几个标准轻松搞定 - 变量人生001
  • Anthropic语义压缩层蒸发:从过程可控到结果可信的范式迁移
  • 从安装到上手,OpenClaw 本地 AI 自动化工具完整指南
  • 抚州 黄金投资金条选购要点分享 - 润富黄金回收
  • G-Helper高效指南:5分钟掌握华硕笔记本性能优化神器