哈喽大家好这里是你的技术博主朋友。最近在折腾一个小项目的时候我在标题里开了一个玩笑说要“用 DeepseekV4Flash 做一款旮旯给姆”。可能有的读者看到“旮旯给姆”会愣一下其实这就是 galgame 的中文谐音也就是美少女恋爱题材的视觉小说游戏。这个项目本身没有多复杂但是整个过程走下来从 AI 剧本生成、角色立绘、语音合成再到把内容整合进引擎里跑起来踩坑和收获都不少。所以这篇文章就把这套完整的实操流程整理出来聊一聊如何使用 AI 辅助完成一款 galgame 的从零到一。本文适合这样的读者想做 galgame 但不会画画、写文吃力、没有声优资源同时对 AI 编程和自动化脚本有一定兴趣的开发者。哪怕你完全没接触过视觉小说引擎只要愿意跟着文章一步步操作也能在本地跑通一个可玩的小样章。顺便说一句关于标题里的 “DeepseekV4Flash”这里先不纠结它到底是哪个渠道的模型标识因为不同平台对模型的命名方式会随时调整。本文的重点是“用大模型 API 做内容生产”的整体思路和方法你可以把它替换成任何你实际有权限调用的对话模型、绘图模型和语音模型。好我们正式开始。1. 做一款 galgame 到底需要什么所谓 galgame本质上是一种以文字剧情为核心、配合角色立绘、背景音乐和语音来推动玩家体验的视觉小说。它的核心不是操作难度而是内容量剧本字数、人物关系、分支选择、CG 数量和语音包。在过去一个人做 galgame 几乎不可能因为写 10 万字剧本、画几十张立绘、找声优录音每一项都需要专业能力和大量时间。但现在情况不同了AI 在文字创作、图像生成和语音合成上都有了不错的可用性个人开发者完全可以借助 AI 工具链把内容生产速度提升一个量级。1.1 我理解中的“AI 做 galgame”是什么我更愿意把这种开发方式叫做“AI 辅助内容工厂”而不是“让 AI 自动做游戏”。AI 负责的内容包括剧情大纲和分支脚本的生成减少从空白文档开始的畏难感。角色设定的头脑风暴例如性格、口头禅、与主角的关系。立绘和 CG 的生成这一步可以大幅降低美术门槛。角色语音的合成让每个角色有声音。代码层面的辅助比如生成 RenPy 脚本、批量处理资源文件。而开发者负责的内容包括决定游戏的核心主题和玩法。把控剧情质量、筛选 AI 生成内容的逻辑漏洞。将文本、图片、音频资源整理进游戏引擎。完成测试、打包和发布。简单说AI 负责“量大管饱”的工作人类负责“审美和把关”。1.2 为什么选择 RenPy 作为游戏引擎视觉小说领域最常用的开源引擎是 RenPy它有两个显著优点。一是脚本语法接近自然语言学习成本很低。你看下面这段就能明白大概意思label start: scene bg classroom show sara happy at center sara 今天也要一起加油哦 menu: 回应她: jump reply_yes 假装没听到: jump reply_no二是 RenPy 支持直接导入图片、音频、视频并且跨平台打包。对个人开发者来说不需要写复杂的渲染逻辑只用处理内容本身就好。所以本文的整体技术路线就是AI 生成内容 → Python 脚本做格式清洗 → 整理成 RenPy 项目 → 本地运行验证。2. 环境准备与版本说明为了不让你在环境上卡住我先给出本文开发环境的基本情况。考虑到读者情况不同这里只写一个参考基线如果你的版本不太一样不影响整体操作。2.1 基础环境清单项目推荐配置说明操作系统Windows 10/11 或 Ubuntu 20.04本文示例在 Windows 下完成Python3.9 到 3.11主要用来写资源处理和 API 调用脚本RenPy SDK8.x 系列官方免费下载自带编辑器AI 文本模型任意已授权的大模型 API本文用 OpenAI 兼容接口示例AI 绘图本地 SD WebUI 或在线绘图 API需要输出 PNG 图片AI 语音在线 TTS API 或本地 TTS 模型需要输出 WAV/MP3需要注意的是AI 平台的模型名称和接口地址变动比较频繁。文章中的示例代码使用了通用的请求格式并把关键参数做成了占位符你需要根据自己的实际服务商信息替换。2.2 安装 Python 依赖整个项目会用到requests库、Pillow图片处理库以及json、os等标准库。创建项目目录后执行下面的命令来安装依赖mkdir gala-ai-demo cd gala-ai-demo python -m venv venv venv\Scripts\activate pip install requests pillow如果你使用的是 Linux 或 macOS激活虚拟环境的命令是source venv/bin/activate2.3 下载 RenPy SDK到 RenPy 官网下载对应系统的 SDK 压缩包解压到一个没有中文路径的目录。解压后目录里有一个renpy.exeWindows打开它就能看到 RenPy 的启动器界面。第一次启动时RenPy 会自动关联示例项目。我们后面会手动创建一个我们的游戏项目然后让 RenPy 指向它。3. 核心思路拆解从需求到可玩 Demo在做代码之前我们先把这个项目的流程拆清楚避免边写边乱。3.1 游戏题材设定我给演示项目设定的题材叫《夏日观测站》。故事背景是主角暑假回到海边小镇在一座废弃的天文观测站遇到了三位性格各异的女孩。随着相处主角逐渐发现观测站背后隐藏的星空异常事件并需要在关键时刻做出选择。这个设定的好处是场景比较少避免生成大量背景图。人物关系简单三条个人线可以独立展开。有一个轻科幻的悬念让剧情不至于太日常。当然你完全可以用你自己的设定。这里只是提供一个可操作的样例。3.2 整体内容生产流程整个内容生产分为四步用文本模型生成大纲、分章节剧本和角色设定。用绘图模型生成角色立绘、表情差分和背景图片。用语音模型为角色生成对白音频。将以上所有资源通过脚本整理成 RenPy 可识别的格式并编写游戏脚本。需要注意的是AI 生成的文本不能直接丢进游戏。因为大部分模型生成的文字会带有无意义的重复、过长的描写、不符合角色口吻的表达必须经过清洗和改写。我在后面的实战部分会给你一个文本清洗脚本。3.3 为什么需要“脚本化”管理资源很多新手在手动做游戏时会遇到一个很常见的现象图片几十张、音频几百个、文本散落在 Word 或者记事本里最后根本分不清哪个文件对应哪个对话。所以我们在项目开始前就要约定一组文件命名规范例如立绘文件命名chara_名字_表情.png背景文件命名bg_场景_序号.png语音文件命名voice_章节编号_句子编号.wav剧本文件命名script_章节.rpy这套规范会让后期整合变得非常轻松。4. 完整实战用 AI 生成内容并整合进 RenPy下面进入正题。这一节的内容会比较多我按阶段拆开讲。4.1 创建项目结构在gala-ai-demo目录下我们规划这样一个目录结构gala-ai-demo/ ├── gen_script.py # 调用文本模型生成剧本 ├── gen_voice.py # 调用TTS生成语音 ├── build_assets.py # 整理图片资源 ├── output/ # 生成结果统一放这里 │ ├── text/ # 生成的剧本文本 │ ├── images/ # 生成的图片 │ └── voice/ # 生成的语音 └── game/ # RenPy 项目目录先动手创建这些目录mkdir output mkdir output\text mkdir output\images mkdir output\voice mkdir game在正式编写游戏前我们需要先通过 AI 生成一批基础素材。4.2 使用文本模型生成剧情大纲这是一个非常典型的文本生成任务。我先写一个gen_script.py它通过通用的对话接口向模型发送请求要求模型输出《夏日观测站》的第一章节剧本。因为不同平台的接口格式可能不同我统一使用 OpenAI 兼容的请求格式。这里用到了requests库# 文件路径gala-ai-demo/gen_script.py import requests import json import os # 请替换为你的实际服务地址和密钥 API_ENDPOINT https://your-api-endpoint/v1/chat/completions API_KEY os.environ.get(AI_API_KEY, your-api-key-here) def chat_text(prompt, modelyour-model-id): headers { Content-Type: application/json, Authorization: fBearer {API_KEY} } payload { model: model, messages: [ {role: system, content: 你是一名视觉小说剧本作家。}, {role: user, content: prompt} ], temperature: 0.8 } resp requests.post(API_ENDPOINT, headersheaders, jsonpayload, timeout60) resp.raise_for_status() data resp.json() return data[choices][0][message][content] if __name__ __main__: prompt 请为视觉小说《夏日观测站》写第一章剧本。 要求 1. 主角来到海边小镇的废弃天文观测站。 2. 遇见的第一个女主角叫小夕她正在观测站门口踮脚看星空。 3. 场景包括海边公路、观测站门前、观测站内部。 4. 输出格式严格使用 【场景观测站门前】 - 角色立绘小夕好奇表情 - 台词小夕你是谁这么晚还来观测站 - 旁白...... result chat_text(prompt) with open(output/text/chapter1.txt, w, encodingutf-8) as f: f.write(result) print(剧本生成完毕保存在 output/text/chapter1.txt)这里有几个关键点值得说明。首先是temperature参数。它控制随机性数值越高生成内容越随机越低越稳定。剧本创作可以给 0.8 左右让文风更轻松。其次是提示词里的格式要求。如果你不给模型限定输出格式它可能会给你一段大段散文后期拆分会非常痛苦。所以在提示词里明确【场景】、- 角色立绘、- 台词这种结构能大幅减少二次清洗的工作量。4.3 清洗剧本文本并转换为 RenPy 脚本AI 生成出来的文本往往有这些小问题混入了解释性的话“好的以下是你要求的剧本……”空行和符号不统一。对话中的冒号有全角半角混用。场景名和立绘信息嵌套在描述里。我写了一个build_rpy.py用来将我们约定好的格式转换成 RenPy 的rpy脚本文件。注意这个脚本是针对上面提示词约定的格式来写的如果你改了提示词格式需要同步调整解析规则。# 文件路径gala-ai-demo/build_rpy.py import re def parse_chapter(filepath): with open(filepath, r, encodingutf-8) as f: content f.read() lines content.splitlines() rpy_lines [] rpy_lines.append(label chapter1_start:\n) for line in lines: line line.strip() if not line: continue # 解析场景行【场景观测站门前】 m re.match(r^【场景(.?)】$, line) if m: scene_name m.group(1) rpy_lines.append(f scene bg_{scene_name}\n) rpy_lines.append(f with fade\n) continue # 解析立绘行- 角色立绘小夕好奇表情 m re.match(r^- 角色立绘(.?)(.)$, line) if m: chara m.group(1) emotion m.group(2) rpy_lines.append(f show {chara} {emotion}\n) continue # 解析台词行- 台词小夕你是谁 m re.match(r^- 台词(.?)(.)$, line) if m: chara m.group(1) text m.group(2) rpy_lines.append(f {chara} \{text}\\n) continue # 解析旁白行- 旁白...... m re.match(r^- 旁白(.)$, line) if m: text m.group(1) rpy_lines.append(f \{text}\\n) continue rpy_lines.append( return\n) return .join(rpy_lines) if __name__ __main__: result parse_chapter(output/text/chapter1.txt) with open(game/script/chapter1.rpy, w, encodingutf-8) as f: f.write(result) print(RenPy脚本生成完毕保存在 game/script/chapter1.rpy)这个解析脚本的意思很直白按行读取文本如果匹配到场景、立绘、台词、旁白就转成对应的 RenPy 语法。它不是一个通用的转换器而是一个参考实现。在你自己做项目时最需要改的是正则匹配规则和 RenPy 语句的映射逻辑。4.4 使用绘图模型生成立绘和背景立绘这里我给一个建议不追求一次生成完美图而是分角色、分表情生成。比如小夕这个角色我在绘图模型里给出这样一段提示词girl, silver short hair, blue eyes, summer school uniform, standing near an old observatory, evening sky, stars, clean lineart, anime style illustration, full body character design, transparent background not required, soft lighting如果你想生成单个表情的状态图可以具体描述表情差异开心happy expression, closed eyes, smile好奇curious expression, eyes wide open, leaning forward如果你使用本地 Stable Diffusion WebUI可以通过命令行调用接口。但如果你只是快速验证素材流程最简单的做法是先用在线绘图工具生成几张 16:9 的背景图和立绘然后放入output/images。在实际项目中我一般会生成 1024x576 的背景和 832x1216 的立绘。RenPy 在运行时会对图片做缩放所以不用担心尺寸有细微差别但尽量保持一致会更干净。4.5 使用 TTS 生成角色语音语音这块我写一个gen_voice.py示例。你需要准备一个可用的文本转语音服务各大云平台都有这里我们还是用通用的 HTTP 请求方式。# 文件路径gala-ai-demo/gen_voice.py import os import requests TTS_ENDPOINT https://your-tts-api.example/synthesize TTS_TOKEN os.environ.get(TTS_TOKEN, your-token-here) def text_to_speech(text, output_path, voice_idfemale-1): headers { Authorization: fBearer {TTS_TOKEN}, Content-Type: application/json } payload { text: text, voice: voice_id, format: wav } resp requests.post(TTS_ENDPOINT, headersheaders, jsonpayload, timeout120) resp.raise_for_status() with open(output_path, wb) as f: f.write(resp.content) print(f语音已保存: {output_path}) if __name__ __main__: lines [ (xiao_xi_line_001, 你是谁这么晚还来观测站), (xiao_xi_line_002, 这里已经很久没人来了不过今晚的星星特别好看。), ] for file_id, text in lines: text_to_speech(text, foutput/voice/{file_id}.wav)分析一下这段代码。voice_id参数对应服务商提供的不同音色有的偏少女有的偏成熟需要你按当前服务商的实际参数填。format建议先输出 WAV因为 WAV 不用额外解码RenPy 对 WAV 的兼容性最稳定。如果服务商只支持 MP3也没有问题RenPy 也能播放 MP3。有一点想提醒大家合成语音的文本一定要用清洗后的台词不要直接把 AI 生成出来的文本拿去发音。否则会出现标点符号被读出来、英文单词混读、情绪和台词不匹配等问题。4.6 组装 RenPy 项目现在我们手上已经有三类素材描述剧情流程的rpy脚本、放在output/images里的图片、放在output/voice里的语音。但由于我们的解析脚本目前只生成了chapter1.rpy立绘和语音还没有在游戏脚本中被正确调用。这里需要手动在 RenPy 脚本中补充图片定义和语音播放指令。先来看项目里的game/script/chapter1.rpy最终示例# 文件路径game/script/chapter1.rpy label chapter1_start: scene bg_road with fade 沿着海边公路走了很久我终于看到了那座废弃的观测站。 scene bg_observatory_door with fade show xiaoxi curious at center xiaoxi 你是谁这么晚还来观测站 play voice voice/xiao_xi_line_001.wav xiaoxi 这里已经很久没人来了不过今晚的星星特别好看。 menu: 问她的名字: jump ask_name 抬头看星星: jump look_star label ask_name: xiaoxi 叫我小夕就好。你是天文爱好者吗 jump chapter1_end label look_star: 我抬起头这才注意到满天的星星亮得不正常。 xiaoxi 你也发现了 jump chapter1_end label chapter1_end: return这里除了常规的scene、show、台词之外有几个关键玩法点。第一是play voice指令。它用来播放指定路径的音频文件路径是相对于game目录的。如果你的语音文件放在game/voice下那么写play voice voice/xiao_xi_line_001.wav就能被正确识别。第二是menu分支。RenPy 的交互就是靠menu和jump实现的。玩家选择不同选项后流程会跳到不同标签继续执行。第三是show xiaoxi curious at center。这句的意思是显示角色立绘并且使用curious这个表情。为了让表情变体生效还需要在项目中定义图片。我们可以在game目录下写一个声明文件# 文件路径game/images.rpy image xiaoxi curious images/xiaoxi_curious.png image xiaoxi happy images/xiaoxi_happy.png image xiaoxi normal images/xiaoxi_normal.png image bg_road images/bg_road.png image bg_observatory_door images/bg_observatory_door.png这样当脚本里执行show xiaoxi curious时RenPy 就会去加载images/xiaoxi_curious.png文件。注意如果你的图片没有严格按这个路径放可以自由修改上面images.rpy中的路径保持文件路径和实际目录一致即可。4.7 运行与验证把上面这些文件都放好之后打开 RenPy 启动器点击“项目”列表旁的“新建项目”项目名称可以填SummerObservatory路径选择我们的gala-ai-demo/game所在的父目录。如果 RenPy 启动器没有自动识别项目目录也可以在启动器界面点击“设置”手动选择一个包含game目录的项目根目录。启动后点击“启动项目”RenPy 就会进入游戏测试界面。你会看到第一屏显示海边公路背景。旁白文字出现在底部文本框。小夕出现在画面中央并说出第一句台词。屏幕下方出现两个选项。如果遇到图片或语音缺失RenPy 会在控制台输出报错信息并且游戏界面显示相应的错误提示。这个流程走通后一款最小可玩的 galgame Demo 就算完成了。5. AI 生成内容的常见问题与排查思路做这个项目的过程中最有价值的其实是排查问题的过程。我整理了几个高频问题方便你遇到时报错知道从哪下手。问题现象常见原因解决思路生成的剧本格式很乱难以解析提示词里没有规定明确的输出格式在提示词中给出模板示例并要求“严格按示例格式输出”RenPy 启动报错ScriptErrorrpy脚本中语法错误或引用了不存在的图片打开错误日志查看行号检查image定义是否齐全立绘显示出来比例不对图片尺寸和角色缩放设置不匹配使用图像工具统一裁剪或在 RenPy 中使用zoom属性调整语音播放不出来路径写错或音频格式不受支持确认音频在game目录下并优先使用 WAV/MP3AI 生成的台词与角色性格不符提示词里缺少人设背景在每次文本生成的提示词中附上角色性格卡片例如“小夕内向、好奇心强”文本模型生成内容重复temperature过低或单次生成长度太长提高温度到 0.8 左右并把长文本拆分为多次生成在线绘图生成的立绘风格不统一模型随机性导致使用同一角色描述前缀并在生成后挑选风格一致的图还有一个很容易被忽略的问题中文标点。RenPy 的对话字符串中如果出现中文双引号内部还有英文引号可能会导致脚本解析异常。这里建议统一使用中文全角标点避免混用。6. 最佳实践与工程化建议当项目只是 Demo 时怎么折腾都行。但如果你想把这款 galgame 做完下面这些经验非常有用。6.1 内容与代码分离不要把所有剧情都写在一个巨大的script.rpy文件里也不要让 AI 直接生成一整本书级的剧本。更推荐的做法是每章一个rpy文件。共用图片定义放在images.rpy。音效和语音路径尽量通过变量管理。游戏设置放gui.rpy但不要轻易乱改。这样做的好处是当剧情需要修改时你只需要打开对应章节文件而不需要在一个 2000 行的文件里滚动查找。6.2 为提示词建立模板库你可以为你的项目准备几套固定的提示词模板角色人设模板。分章节剧情提示模板。分支选项提示模板。立绘生成提示模板。背景图生成提示模板。每次调用模型时只需要替换模板中的“角色名”“场景”“事件”等变量就能保证输出格式稳定。这比每次都现场写一大段提示词要可靠得多。6.3 引入人工校对流程AI 生成的内容可以直接用但很容易犯“剧情中角色突然知道本来不该知道的事”这种逻辑错误。所以建议引入一个简单的校对流程AI 生成初稿。开发者通读标记逻辑问题。将标记的问题反馈给 AI 重新生成对应段落。人工修改后确认定稿。这里不建议让 AI 全自动完成校对因为在长剧情上下文里模型很可能会“滑跪”到另一种设定里导致前后矛盾。人工确认这一环不能省。6.4 资源和版本管理游戏项目中图片和音频体积大、数量多即使个人开发者也建议用 Git 管理脚本和配置。对于体积巨大的资源文件可以后续考虑 Git LFS也可以仅将脚本文件纳入仓库图片保留本地备份。建议目录里额外增加一个archive原始素材目录把 AI 生成的所有原始结果先存放在那里然后再拷贝一份清洗后的进入game。这样万一统一风格需要返工原始数据不会丢失。6.5 注意合规与服务条款使用任何 AI 服务前建议确认以下事项你是否有权调用该接口API Key 是否来自合法授权渠道。生成内容的版权规则特别是用于商业发布时。角色语音是否允许在成品游戏中使用。是否需要在游戏中声明使用了 AI 生成内容。这些事项在不同平台上差别很大所以本文不展开说具体某平台的政策。保持谨慎是对自己的作品负责。6.6 性能优化建议当剧本超过几万字、语音文件上千个时RenPy 项目的体积会膨胀。建议在发布前做三件事将图片压缩为 WebP 格式RenPy 8 支持 WebP体积比 PNG 小很多。将长语音压缩为 96kbps 的 MP3保留音质和体积平衡。尽量复用背景图可以用色温和滤镜微调来制造不同时间段效果而不是重新生成一张新图。7. 一些给入坑者的建议如果你也想做一款自己的 galgame不必一开始就设定“要做 20 小时流程、10 个结局”的大计划。更好的方法是先做一个 5 分钟流程的小 Demo内容只需要一个场景。两个角色。三到五句台词。一个分支选项。一个结局。把这个 Demo 完整跑通你就算是掌握了整个技术流水线。之后再去扩展角色、章节、CG就只是重复调用已经跑通的工具链而已。AI 生成内容的能力提升很快今天可能需要人工清洗的格式明天可能模型就能直接输出。但无论工具怎么变做 galgame 的核心还是内容和情感体验。技术只是把灵感落地的工具别让工具盖过内容本身。这篇文章聊了一整套从“用 AI 生成剧本”到“整合进 RenPy 引擎”的完整流程重点围绕剧情文本的格式化生成、立绘和语音的资源管理、以及 RenPy 项目的组装与排错。如果你在实操过程中遇到了新的问题欢迎在评论区留言讨论我会尽力帮你排查思路。下一次迭代中你可以继续探索的方向包括为多角色添加动态立绘、通过条件变量做多结局统计、把剧本生成脚本做成带有图形界面的小工具甚至是接入 AI 对话让玩家自由输入文本。这些都是很有意思的进阶玩法完全可以在这个 Demo 的基础上继续扩展。