山东大学创新实训2——基础框架搭建
目录
时间: 2026年3月下旬 - 4月上旬
4月7号,我们小组成员一起完成了StoryEcho沉浸式互动叙事平台的基础框架搭建。我们每一个人都先在自己的电脑上尝试搭建一套可运行的前后端连接环境,目的是通过此过程让我们都更加了解整个项目架构与agent知识。最后,我们初步选择以FastAPI为后端核心、Vue.js为前端载体,实现了从故事模板管理、游戏状态维护到用户交互响应的全流程闭环。本文将从技术选型、核心模块设计、开发难点突破等维度,复盘整个项目的技术实践与进度成果。
一、项目整体架构与技术选型
在开始搭建项目前,我们根据项目书围绕轻量易扩展、开发效率高、前后端解耦三个核心目标进行了技术选型,主要先实现用户输入文字指令(比如 “探索”“攻击”“吃药”),系统自动处理逻辑、更新角色状态,再返回沉浸式剧情描述的功能。
后端:选用FastAPI作为主框架,相比Flask和Django,FastAPI原生支持异步、自动生成OpenAPI文档、Pydantic数据校验的特性,能快速搭建高性能API;搭配Uvicorn作为ASGI服务器,保证异步请求的高效处理;数据层初期采用SQLite3(配合SQLAlchemy),兼顾开发便捷性与轻量部署需求;
前端:采用Vue.js 3(组合式API)开发,配合Axios处理HTTP请求,实现响应式的互动界面;
我们本次在ai的帮助下,仅保留核心 Web 服务依赖,在功能可扩展与部署轻量化之间取得平衡,主要是通过抓取关键词进行对话,但是预留了 langgraph、langchain 等依赖和API key的接口,以支撑未来 AI 叙事能力的拓展需求,在下次进行大模型API的接入测试。
以下是和ai的交流页面,deepseek为我们推荐了项目的最初框架,并提供了后续优化建议:


二、初步架构设计
项目采用前后端分离架构,核心分为三层:
1. 前端交互层:负责故事列表展示、游戏状态渲染、用户输入交互,内置mock逻辑保证后端不可用时的基础体验;
2. 后端服务层:通过FastAPI提供RESTful API,包含故事启动、行动处理、状态管理等核心接口,内置StoryEngine处理叙事逻辑;
3. 数据持久层:基于SQLite3设计用户、存档、结局三张核心表,支持游戏进度持久化与结局收集管理。
三、核心模块的技术实现与进度突破
1. 后端核心:
StoryEngine作为平台的核心,承担了故事模板管理、游戏状态初始化、用户行动解析与响应生成的核心职责,目前已完成基础版本的闭环。
故事模版抽象:我们先撰写了以奇幻和科幻为主题的两个故事,将故事抽象为统一模板结构,包含标题、背景、初始属性、场景描述、任务目标等字段,支持快速扩展新故事。
状态驱动的叙事逻辑:设计了以GameState为核心的状态模型(基于Pydantic校验),包含场景ID、角色属性、背包物品、对话记录、任务进度等维度,确保每次用户行动仅需更新状态即可完成叙事推进;
意图解析与响应生成:针对探索、攻击、查看背包、使用道具等核心用户意图,设计差异化的响应逻辑,例如探索行为随机生成资源获取或场景发现结果等,攻击行为结合角色属性计算命中与伤害,同时加入状态衰减/增益的动态反馈,增强沉浸感;
以logic_referee函数为例,讲解目前项目实现的核心逻辑。该函数负责根据玩家的意图执行游戏规则判定、计算数值变化并生成操作结果描述,首先从游戏状态中取出玩家的操作意图与角色属性,为了避免直接修改原始状态引发异常,会先对角色属性创建一个副本进行操作,同时初始化操作成功状态和结果描述文本。 针对不同的玩家意图,函数实现了对应的规则逻辑:当意图为攻击时,系统会结合角色的力量和运气属性计算命中率,并将命中率限制在10%到90%的合理区间,通过随机数判断攻击是否成功,成功则生成随机伤害值并小幅恢复角色生命值,失败则扣除固定生命值;当意图为使用物品时,优先判断目标是否为治疗类物品,遍历玩家背包查找治疗药水,找到后消耗药水并恢复大量生命值,未找到则提示玩家无可用道具,其他物品使用则判定无效果;当意图为对话时,依据角色智力属性判定对话成功率,成功则提升NPC好感度,失败则提示对话无效;当意图为探索时,设定30%的概率随机获得道具,将道具添加到玩家背包中,未触发概率则提示无发现;对于未匹配的意图,会生成默认的无特殊事件描述。 完成所有逻辑判定后,函数会更新操作结果、角色属性和游戏回合数,同时清理临时数据,最终将修改后的游戏状态返回,为后续生成剧情描述提供准确的数值和结果依据。
def logic_referee(self, state: StoryState) -> StoryState:
intent = state["intent"]
attrs = state["attributes"].copy() # 创建副本避免直接修改
success = True
result_desc = ""
# 根据意图执行逻辑判定
if intent == "attack":
# 战斗判定:基于力量和运气
hit_chance = (attrs.get("strength", 10) + attrs.get("luck", 5)) / 2 / 100
hit_chance = min(0.9, max(0.1, hit_chance)) # 限制在10%-90%之间
success = random.random() < hit_chance
if success:
damage = random.randint(5, 20)
result_desc = f"成功击中敌人,造成{damage}点伤害!"
# 战胜恢复体力
attrs["hp"] = min(100, attrs.get("hp", 100) + 5)
else:
result_desc = "攻击落空了!敌人躲过了你的攻击。"
attrs["hp"] = max(0, attrs.get("hp", 100) - 10)
elif intent == "use":
# 使用物品判定
target = state.get("intent_target", "")
if "药水" in target or "治疗" in target or "血" in target:
# 检查是否有治疗药水
inventory = state.get("inventory", [])
found = False
for i, item in enumerate(inventory):
if "药水" in item or "治疗" in item:
state["inventory"].pop(i)
attrs["hp"] = min(100, attrs.get("hp", 100) + 30)
result_desc = "你喝下了治疗药水,恢复了30点生命值!"
found = True
break
if not found:
result_desc = "你没有治疗药水!"
success = False
else:
result_desc = f"你使用了{target},但似乎没有什么效果。"
elif intent == "talk":
# 对话判定:基于智力
success = random.random() < (attrs.get("intelligence", 10) / 100)
if success:
result_desc = "对方对你的话产生了积极回应。"
# 增加好感度
if "npc_1" in state.get("relationships", {}):
state["relationships"]["npc_1"] = min(100, state["relationships"]["npc_1"] + 5)
else:
state["relationships"]["npc_1"] = 50
else:
result_desc = "对方似乎对你的话不感兴趣。"
elif intent == "explore":
# 探索判定:发现物品
if random.random() < 0.3:
found_items = ["金币x10", "草药", "神秘钥匙", "魔法水晶"]
item = random.choice(found_items)
if "inventory" not in state:
state["inventory"] = []
state["inventory"].append(item)
result_desc = f"你在探索中发现了{item}!"
else:
result_desc = "你仔细探索了周围,但没有发现特别的东西。"
else:
result_desc = f"你{state['intent_target']},但似乎没有特别的事情发生。"
结局触发机制:基于角色生命值(HP≤0)、回合数(≥15)等条件设计多结局触发逻辑,为后续扩展多分支叙事打下基础。 截至目前,后端已完成6个核心API接口的开发:健康检查、故事列表查询、故事启动、行动处理等,且通过CORS跨域配置实现与前端的无缝对接。
2. 前端交互:响应式互动界面
前端基于Vue 3组合式API开发,核心实现了故事选择-游戏启动-行动交互-结局展示的全流程界面,重点突破了以下技术点:
响应式状态管理:通过ref管理游戏启动状态、用户输入、加载状态等核心数据,利用onMounted生命周期完成故事列表的初始化加载;
Mock降级策略:考虑到后端开发与部署的阶段性,为所有API请求设计Mock逻辑。当后端服务不可用时,自动加载模拟故事数据、生成模拟游戏状态,保证前端体验的完整性;
沉浸式交互细节:实现对话窗口自动滚动到底部、角色属性可视化(不同属性绑定差异化颜色/emoji)、快捷行动按钮等细节,降低用户操作成本;
结局可视化:将不同结局类型(悲剧/完美/普通/中立)映射为差异化的视觉文案,增强叙事闭环的仪式感。 目前前端已完成所有核心交互场景的开发,界面适配基础的桌面端浏览,支持游戏重启、快捷行动、状态查看等核心操作,且代码结构清晰,便于后续扩展。
3. 数据持久层:轻量级存档系统
基于SQLite3设计了轻量化的存档系统,主要包括users(用户信息)、saves(游戏存档)、endings(结局收集)三张表,通过外键关联用户与存档,存档表存储状态JSON字符串,兼顾灵活性与查询效率;实现了save_game(存档)、load_save(读档)、get_user_saves(查询用户存档列表)等方法,支持游戏进度的持久化与回溯。后续可扩展基于时间戳的自动存档、多存档位管理等功能。
以save_game作为例子,该函数主要用来实现游戏存档功能,把玩家当前的游戏进度永久保存到数据库里,方便下次读取继续玩。我们采用 SQLite 本地数据库作为存储载体,整体流程清晰且安全。 函数首先接收存档ID、用户ID、故事ID、场景预览、进度百分比和完整游戏状态这些关键数据,然后连接到项目指定的数据库文件。连接成功后,通过数据库游标执行写入操作,使用 INSERT OR REPLACE语句实现智能存档逻辑:如果这个存档ID已经存在,就自动覆盖旧数据;如果不存在,就新建一条存档记录。 在写入数据时,代码会把当前时间自动生成并保存为时间戳,方便玩家查看存档时间;同时把复杂的游戏状态字典通过json.dumps转换成 JSON 字符串,让原本无法直接存入数据库的结构化数据(比如角色属性、背包、剧情进度)可以被完整存储,且支持中文正常保存。数据写入完成后,执行提交操作确保数据真正落地,最后关闭数据库连接,避免资源占用。代码展示如下:
def save_game(self, save_id: str, user_id: str, story_id: str,
scene_preview: str, progress_percent: int, state: Dict):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
INSERT OR REPLACE INTO saves
(save_id, user_id, story_id, timestamp, scene_preview, progress_percent, state_json)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (save_id, user_id, story_id, datetime.now().isoformat(),
scene_preview, progress_percent, json.dumps(state, ensure_ascii=False)))
conn.commit()
conn.close()
四、当前功能展示
以下是我们当前制作的前端页面,首先可以在两个主题中进行选择

点击左侧的选项,进入迷雾森林传说的交互页面,左侧显示角色属性、背包物品、和当前任务,右侧主页面显示交互文字
以下为赛博朋克2077:觉醒的游戏交互页面,可以看到文字提示、角色属性、背包、任务均不相同。

可以输入文字,通过获取关键词来进行交互

五、技术难点与解决方案
1. 状态一致性维护
由于用户每次行动都需基于当前状态生成响应,并更新状态,我们采用单一状态源设计,所有叙事逻辑仅操作GameState对象,避免状态分散;后端通过active_sessions字典维护当前活跃会话的状态,会话ID作为唯一标识,前端请求时携带会话ID,确保状态精准匹配;Pydantic模型校验状态结构,避免非法状态更新导致的逻辑异常。
2. 前后端交互的容错性
前端依赖后端API,但开发/部署阶段可能出现后端不可用的情况。我们在前端为所有异步请求添加try-catch逻辑,捕获异常后自动触发Mock逻辑;让Mock数据与真实API返回结构保持一致,确保前端无需修改渲染逻辑即可无缝切换;加载状态(isLoading)全局管理,避免用户重复提交操作。
3. 叙事逻辑的可扩展性
由于我们现在项目初期仅支持简单的意图解析,未来需扩展AI驱动的自由叙事,所以我们将StoryEngine设计为独立类,核心方法(process_action、handle_explore等)解耦,便于后续替换为AI生成逻辑;预留了langgraph和langchain依赖,为后续接入大语言模型(LLM)做准备;状态模型(GameState)抽象为通用结构,不绑定具体故事逻辑,支持不同题材故事的适配。
六、后续技术规划
1. AI能力集成:基于langchain/langgraph接入OpenAI API,实现自由文本输入的意图解析与叙事生成,替代当前硬编码的响应逻辑;
2. 多分支叙事扩展:设计场景跳转逻辑,支持基于用户选择的分支剧情,完善结局系统;
3. 前端体验升级:添加动画效果、音效、移动端适配,提升沉浸感;美化画面。
七、总结
StoryEcho的核心搭建过程,是一次从需求抽象到技术落地的完整实践:从互动叙事的核心需求出发,选择适配的技术栈,通过分层设计解耦核心逻辑,同时兼顾开发效率与可扩展性。目前项目已实现基础的互动叙事闭环,验证了FastAPI+Vue.js技术栈在轻量级互动应用中的适配性,也为后续AI增强、多分支叙事扩展打下了坚实的技术基础。 互动叙事的魅力正是在于用户既是读者,也是作者,后续我们将持续迭代StoryEngine的叙事能力,探索AI与互动叙事的结合点。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)