下载 App

如何在 TapTap 小游戏中接入 AI 游戏助手:从零开始的完整分享

精华修改于04/17763 浏览开发交流
大家好,我是「深渊炼狱:堕落之塔2」的开发者,游戏还在开发中。最近给游戏加了一个 AI 游戏助手功能——玩家可以在游戏内直接跟 AI 对话,问攻略、问合成配方、问兑换码,甚至聊聊天吹吹水。
测试后玩家反馈出乎意料地好,很多玩家说"比查攻略方便多了"。这里把完整的开发过程、踩过的坑、以及一些心得分享给大家,希望对想做类似功能的开发者有帮助。
horizontal linehorizontal line

一、为什么要在游戏里加 AI?

我的游戏有 42 个仆从、67 个遗物、暗品合成配方、天赋加点、装备套装……系统比较多。玩家经常在群里问:
"XX暗品怎么合成?需要哪两个金品?"
"天赋点怎么加最优?"
"有没有兑换码?"
"新手刚开始怎么玩?"
我一个人根本回答不过来。于是想到:能不能让 AI 来当 24 小时在线的客服?
而且 AI 不只能答游戏问题,玩家问个数学题、聊个天也行,增加游戏的粘性和趣味性。
horizontal linehorizontal line

二、整体架构:服务端代理模式

为什么不在客户端直接调 API?

一开始我想在客户端直接请求大模型 API,但很快发现几个致命问题:
1. API Key 暴露:客户端代码容易被反编译,Key 泄露 = 钱包遭殃
2. 安全风控:没法做频率限制、敏感词过滤
3. 灵活性差:换模型、改提示词都要发版更新
所以最终采用了 服务端代理 架构:
玩家输入问题
    ↓
客户端 → [RemoteEvent] → 服务端 AIProxyServer
    ↓
服务端 → [HTTP POST] → 大模型 API(豆包)
    ↓
服务端 ← [JSON Response] ← 大模型返回
    ↓
客户端 ← [RemoteEvent] ← 服务端转发回复
    ↓
玩家看到 AI 回复

核心代码结构

scripts/
├── network/
│   ├── AIProxyServer.lua    -- 服务端:转发请求、管理对话历史
│   ├── AIProxyShared.lua    -- 共享:事件名定义
│   └── AIProxyClient.lua    -- 客户端:发送问题、显示回复
└── AIChatPanel.lua          -- UI:聊天界面
服务端核心逻辑其实非常简单,就三步:
```lua
-- 1. 收到客户端消息
SubscribeToEvent("C2SAICHATREQ", function(, eventData)
    local userMessage = eventData["Message"]:GetString()
-- 2. 构造请求,发给大模型
local messages = {
    { role = "system", content = systemPrompt },
    -- ... 历史对话 ...
    { role = "user", content = userMessage },
}
http:Create()
    :SetUrl(API_URL)
    :SetMethod(HTTP_POST)
    :AddHeader("Authorization", "Bearer " .. API_KEY)
    :SetBody(cjson.encode({ model = MODEL_ID, messages = messages }))
    :OnSuccess(function(_, response)
        -- 3. 解析回复,转发给客户端
        local data = cjson.decode(response.dataAsString)
        local reply = data.choices[1].message.content
        SendToClient(conn, "S2C_AI_CHAT_RESP", { Reply = reply })
    end)
    :Send()
end)
```
horizontal linehorizontal line

三、系统提示词:AI 好不好用,80% 取决于这个

这是我花时间最多、也是效果最明显的部分。系统提示词的质量直接决定了 AI 回答的准确度。

血泪教训:别偷懒写模糊描述

我最初的提示词是这样的:
你是一个塔防游戏的助手,游戏有多种仆从和遗物,请帮助玩家回答问题。
结果 AI 的回答全是瞎编的——编造不存在的仆从名字、虚构合成配方、胡说游戏机制。大模型不了解你的游戏,它只会"合理地编造"。

正确做法:把真实游戏数据全部喂给它

我最终写了一份 200 多行的系统提示词,涵盖了游戏的所有核心数据:
```lua
local SYSTEM_PROMPT = [[你是「深渊炼狱:堕落之塔2」的AI游戏助手。
仆从系统(共42个)
普通仆从名录
召唤概率
灰50%、血30%、蓝15%、紫4%、金0.9%、暗0.1%
50抽保底金品
遗物系统(共67个)
...
天赋系统
6个天赋,共8点,分3层投点:
基础层:魔力亲和(max3)、战斗本能(max3)、灵魂共鸣(max3)
进阶层(需3基础点):深渊意志(max3)、堕落赐福(max3)
精通层(需6点):末日审判(max1)
...]]
```

数据怎么来?直接从代码里扫

别让嗒啦啦手动抄,容易出错。我的做法是 直接扫描游戏源码,提取真实的配置数据:
仆从名称和属性 → 扫 Config.SPIRITS
配置表
暗品合成配方 → 扫 Config.DARK_RECIPES
遗物数量和效果 → 扫 Config.RELICS
天赋/技能数据 → 扫 Config.LORD_TALENTS
、Config.LORD_SKILLS
召唤概率 → 扫 Config.SUMMON_RATES
代码是唯一的真相来源,文档会过时,代码不会。

关键技巧:限制回复长度

大模型默认回复很长,但游戏聊天窗口空间有限,太长体验很差。两层限制:
```lua
-- 1. 提示词里明确告诉它
⚠️ 重要:所有回复必须控制在300字以内。
-- 2. API 参数里硬限制
{ model = MODELID, messages = msgs, maxtokens = 512 }
```
horizontal linehorizontal line

四、动态数据注入:让 AI "实时更新"

静态提示词解决了大部分问题,但有些数据是 运行时动态变化 的,比如:
1.兑换码:GM 随时可能发布新兑换码
2.版本更新日志:每次发版内容不同
3.活动状态:联动活动是否开启

兑换码的动态读取

我的游戏有 GM 广播系统,GM 创建的兑换码会通过排行榜附加数据广播给所有玩家。AI 助手服务端也可以读取这份数据:
```lua
-- 服务端定期从排行榜读取 GM 广播数据
local function refreshCDKList()
    serverCloud:GetRankList("gmbroadcastver", 1, 1, {
        ok = function(rankList)
            local broadcastData = rankList[1].score.gmbroadcastdata
            local cdkList = broadcastData.gmConfig.cdkList
        -- 提取通用码(type=1),格式化奖励
        for _, cdk in ipairs(cdkList) do
            if cdk.type == 1 then
                -- 缓存到内存,拼入系统提示词
            end
        end
    end
})
end
```
然后在构建系统提示词时动态拼接:
lua
local function buildSystemPrompt()
    -- 每 5 分钟刷新一次 CDK 缓存
    if os.time() - lastRefresh >= 300 then
        refreshCDKList()
    end
    return SYSTEM_PROMPT_BASE .. buildCDKSection() .. "\n" .. CHANGELOG
end
这样 GM 发布了新兑换码后,AI 最迟 5 分钟内就能告诉玩家。玩家问"有没有兑换码"时,AI 会直接列出当前可用的兑换码和对应奖励。
horizontal linehorizontal line

五、对话历史管理

只有单轮对话的 AI 体验很差——玩家问"那它怎么合成?",AI 不知道"它"是什么。

方案:每连接独立的对话历史

```lua
local chatHistories = {}  -- connKey -> messages[]
-- 每次对话,把完整历史发给大模型
local messages = {
    { role = "system", content = systemPrompt },
}
for _, msg in ipairs(history) do
    table.insert(messages, msg)
end
-- 限制历史轮数,避免 token 爆炸
local MAXROUNDS = 10  -- 保留最近 10 轮
while #history > MAXROUNDS * 2 do
    table.remove(history, 1)
end
```
注意:玩家断开连接时要清理历史,避免内存泄漏。
lua
CM.OnDisconnect("AIProxy", function(conn, connKey)
    chatHistories[connKey] = nil
end)
horizontal linehorizontal line

六、踩过的坑

坑 1:提示词里的数据和游戏实际不一致

这是最严重的问题。我最初写提示词时凭记忆写的,结果:
1.写了"30章x10关"→ 实际是 100 章
2.写了"遗物共 63 个"→ 实际是 67 个
3.写了"暗品合成需要 3 个金品"→ 实际是禁法书 + 2 个金品
4.写了"天赋 3 选 1"→ 实际是投点系统
解决方案:从代码中全量提取数据,逐字段校对。这个过程很枯燥但非常值得。

坑 2:AI 回复太长导致 JSON 解析失败

大模型有时回复特别长,超过网络传输限制或解析 buffer,导致 JSON 截断。
```lua
-- 设置 maxtokens 限制
{ maxtokens = 512 }
-- 同时在错误处理中给友好提示
:OnSuccess(function(_, response)
    local ok, data = pcall(cjson.decode, response.dataAsString)
    if not ok then
        reply = "AI回复内容过长导致解析失败,请换个简短的问题试试~"
    end
end)
```

坑 3:不要忘记错误处理

网络请求随时可能失败——超时、API 限流、余额不足。每种情况都要有友好的提示:
lua
:OnError(function(_, statusCode, error)
    if statusCode == 0 then
        hint = "请求超时了,试试问简短一点的问题~"
    elseif statusCode == 429 then
        hint = "AI 太忙了,请稍后再试~"
    else
        hint = "网络繁忙,请稍后再试~"
    end
end)

坑 4:提示词中加上"不要编造"

即使喂了完整数据,大模型有时还是会"发挥创意"。明确告诉它:
请基于上述真实游戏数据作答,不要编造不存在的功能或道具。
horizontal linehorizontal line

七、大模型选择

我用的是火山引擎的 豆包大模型(doubao-seed-2-0-pro),原因:
中文能力强,游戏场景本地化好
API 兼容 OpenAI 格式,接入成本低
价格相对便宜,适合独立游戏开发者
其实换任何兼容 OpenAI Chat Completions 格式的大模型都可以(DeepSeek、通义千问等),代码几乎不用改,只需要换 URL、Key 和模型名。
horizontal linehorizontal line

八、成本控制

AI API 是按 token 计费的,要注意控制成本:
| 措施 | 效果 |
|------|------|
| max_tokens = 512
| 限制每次回复长度 |
| 历史轮数上限 10 轮 | 控制上下文 token 数 |
| 系统提示词精简 | 减少每次请求的固定开销 |
| 提示词里要求"300字以内" | 从源头减少输出 |
假如游戏日活几百人,AI 助手的 API 费用每天大概几块钱,大部分人完全可以接受,并且新人每天还有免费的token使用。
horizontal linehorizontal line

九、效果展示

真实使用场景:
问攻略:"暗品怎么合?推荐先合哪个?" → AI 准确列出所有 11 个暗品的合成公式并给建议
问兑换码:"有福利码吗?" → AI 实时列出当前可用的兑换码和奖励
问天赋加点:"天赋怎么加最强?" → AI 根据真实数据推荐加点方案
闲聊:"给我讲个笑话" → AI 变身聊天陪伴
TapTap
TapTap
horizontal linehorizontal line

十、总结

给小游戏加 AI 助手其实不难,核心步骤就四个:
1. 服务端代理架构:保护 API Key,方便迭代
2. 高质量系统提示词:从代码中提取真实数据,这是效果好坏的关键
3. 动态数据注入:兑换码、活动等运行时数据实时同步
4. 对话历史管理:支持多轮对话,记得清理内存
整个功能我从开始到上线测试大概花了一个多小时,其中大部分时间花在了 校对系统提示词的准确性 上。代码本身不复杂,让 AI 说对才是最难的。
希望这篇分享对大家有帮助,有问题欢迎在评论区交流!
猜你想搜
taptap 制造ai游戏助手接入
别再烧积分了!从每次 2000 到每次 50 的血泪经验截图
别再烧积分了!从每次 2000 到每次 50 的血泪经验
适用场景:所有在用 TapTap Code 开发游戏的小白 难度:★☆☆☆☆ 背景最近群里总有人"炫耀"一次操作花了几千积分,说实话这不是值得高兴的事——这是在告诉所有人你的开发方式有根本性问题。我也走过这条弯路,所以来说说怎么改。 积分消耗的本质是什么积分 = AI 处理的 token 数量 = 你发给 AI 的内容 + AI 回给你的内容所以烧积分的本质只有两种: 你让 AI 做了大量无效/重
精华
82 赞
23 回复
如何提升你游戏中的UI美术水平截图
如何提升你游戏中的UI美术水平
一、请为你的游戏挑选一款合适的字体 很多开发者没有注意到其实UI界面中最重要的元素是字体,一款合适的字体能给整个游戏的界面感官带来蜕变。 请看案例 那么如何挑选适合自己的字体呢? 我总结出了一些小经验可供参考: 黑体:通用 宋体:古风、武侠、修仙 楷体:古风、武侠、修仙 圆体:卡通、动漫、Q版 科技:科幻、未来、电子 顺手分享一个免费可商用字体网站: 当然 如果你不知道自己的游戏适合什么风格
精华
126 赞
44 回复
永恒虚空持续开发日记1——关于游戏中的新名词:场频截图
永恒虚空持续开发日记1——关于游戏中的新名词:场频
写在前边:首先感谢TapTap制造版主大大@汪崽 对于作品潜力的肯定,给与了我积分计划二的权限[表情_不好意思]。这边也在加紧开发改进各种功能中,期望尽快给大家带来成熟的版本。[表情_猫咪举手] 大家好,我是永恒虚空的制作人黑猫不详,大家叫我黑猫就好。从今天开始我将以后置开发日记的形式给大家分享我在TapTap制造中制作的游戏永恒虚空的开发过程,新人希望大家多多关照! 今天先给大家介绍我作品中最重
投票
3 赞
本地部署 AI 对接 TapMaker 指南 —— 以 CodeBuddy 为例V1.1截图
本地部署 AI 对接 TapMaker 指南 —— 以 CodeBuddy 为例V1.1
写在前面 大家好,我是橘猫,和你一样也是TapMaker的萌新玩家。在"全能神"天哥的悉心指导下,我顺利完成了本地开发环境的部署。经过这段时间的实战测试,已经成功打通了「本地开发 → 同步至TapMaker」的完整流程。 以下内容全部来自我的个人实操经验,旨在为同样在探索本地部署的朋友提供一个参考。每个人的电脑环境、网络情况、AI工具版本都不尽相同,文中的步骤仅供交流学习。如果你照着操作后遇到问题
37 赞
21 回复
浅记《阿方的旅程》开发历程截图
浅记《阿方的旅程》开发历程
预计阅读时长10分钟,欢迎您先品鉴游戏,再回来看这篇“流水账” 这是我第一次实际接触“用自然语言制作游戏”,也是我第一次接触游戏开发工作,所以一切都是从零开始,跌跌撞撞,懵懵懂懂。[表情_豹哭] 我是通过获得的本次开发资格,6月22日晚,在微信公众号收到了测试资格的消息,最开始公布主题“跳跃”的时候,脑子里最先想到的就是几款非常经典的游戏「马里奥」「Flappy Bird」「Doodle Jump
10 赞
1 回复
01:29
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,截图
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,
视频内容只是一部分, 本游戏耗时3个月,目前完成进度百分之80, 是生存游戏,进入修仙界,走剧情找到宗门加入, 这时游戏才是真正开始, 提升实力境界后就可以变强,获取功法法术法宝, @视频内是游戏里挑战妖族入侵一种主流玩法,游戏就是围绕着这个来进行, 还有很多地方可以战斗,获得资源修炼变强,比如去藏书阁学习功法, 去法宝楼抽法宝,每一个宗门数十个法宝抽取 去修仙界探索,获得各自的资源,可能遇见妖兽
1 赞
3 回复
01:07
我给制造开发了一个半自动的开发工作流截图
我给制造开发了一个半自动的开发工作流
随着多模态模型识图能力增强,尝试一下AI 是否能自己修复bug,自己检查。 1,基于画面修复代码 2,点击TapTap制造 菜单,切换屏幕显示 3,截图验证 刚跑通一个小闭环,给大家分享一下 随着模型能力增强,Token费用走低,这种半自动开发是未来常态了
1 赞
2 回复
01:13
【游戏自荐】《王朝崛起》——一个人做的2D骑马砍杀,但真的上头截图
【游戏自荐】《王朝崛起》——一个人做的2D骑马砍杀,但真的上头
略沙盒,玩法硬核,还在修bug,但真的上头 先声明:我不是托,是开发者自己来安利的。如果你喜欢《骑马与砍杀》那种从零拉起部队、跑商、招降将领、攻城叛变的玩法,那这款游戏大概率会对你的胃口。 一、这游戏玩什么? · 超大的2D沙盒地图:64座城市 + 128个村庄,四大势力割据,满地图的蛮族部落。· 动态世界 & AI:AI势力之间会自己宣战、结盟、叛变;武将忠诚度低了会自立为王,最多能冒出8个新势
13 赞
7 回复
游戏自荐《少女终焉契约》截图
游戏自荐《少女终焉契约》
之前玩放置类型的rpg游戏的时候我就在想,现在游戏的操作有的太过于繁琐了,有没有一款休闲一点的,想上线就上线,离线的时候角色能自动行动的游戏呢?感谢TapTap制造,我按照我的想法开发出了现在这款游戏。 一、故事背景和UI 游戏的故事背景是传统的异世界穿越故事,玩家被女神召唤到异世界,随后组建工会,招募美少女,打怪升级探索世界。所以我选择了更加二次元萌系画风的UI风格,主页为各个主要的功能,点开来
8 赞
3 回复
【Tap make 塔拉拉之立项干货】萌新看过来!截图
【Tap make 塔拉拉之立项干货】萌新看过来!
题外话:本人也是tap make 使用者之一。塔啦啦忠实信徒、天哥忠实拥护者、八年游戏策划经验的低级策划。但是!我已经做出来一款5000+热度、且稳定可更新的框架、并且还在持续产出更多游戏内容的橘猫! 这几天正好在开新坑。我是3月初加入的tapmake大家庭。两周时间于3月25日将这个作品上架。当时的全凭感觉摸索。如今,自己也是一个有自己项目的小菜鸡了。今天,就来分享一下,如何高效的制作一款高大上
投票精华
69 赞
24 回复