文档 工具
头顶气泡与本地模型
让游戏里任意单位以任意身份头顶弹出对话气泡;接上本地大模型,一句话进、一句回复出在单位头上。
气泡是观赏层:不影响胜负,适合直播、解说、调试。
- 任意单位、任意身份说话;多个单位可以同时说;
- 每个气泡的字号、颜色、宽度、尾巴、透明度、打字速度都能单独定制;
- 能直接接本地大模型(LM Studio),支持流式输出:边生成边更新气泡。
从 Bot 里用
最简单的方式是 SDK 自带的 say:
g.say(hero, "跟我冲!", seconds=4)
启动和界面
最省事:远见首页「控制中心」——先点「本地大模型 → 启动并载入模型」(LM Studio 本地服务 + 把配好的模型载进显存),再点「头顶聊天气泡 → 启动」。卡片上能看日志、停止、重启。
界面在远见左侧的「头顶气泡」页:让单位说话(选单位、写字、调样式、和模型对话)、农民茶话会、镜头对白、战况触发、模型设置,按顶栏选的实例操作。
命令行也可以:
python speech/speak_launch.py # 起本地模型服务 + 载入模型并预热 + 起气泡接口
python speech/speak_launch.py --restart # 改了代码后重起接口
python speech/speak_launch.py --stop # 停接口,并把模型从显存卸掉
每一步都是「在就跳过」,重复运行没有副作用。
HTTP 接口
默认 http://127.0.0.1:8872/(端口在 openwar3.json 的 ports.speech),任何程序都能调。
让单位说话 POST /api/say
{
"inst": 16,
"bubbles": [
{ "unit": "0x14A12614", "name": "山丘之王", "text": "跟我冲!" },
{ "unit": "0x14A12924", "name": "大法师", "text": "我来放暴风雪。",
"style": { "font_px": 26, "text_color": "#FFE080", "bg_color": "#C0102040" } },
{ "screen": [960, 110], "key": 1, "name": "旁白", "text": "第一波兽人还有 30 秒到达。",
"style": { "tail": false, "type_ms": 0 } },
{ "world": [-4684, 2644], "key": 2, "text": "集合点", "style": { "font_px": 16 } }
]
}
| 字段 | 说明 |
|---|---|
unit / world / screen | 三选一:跟着单位走(有血条时贴在血条正上方)/ 地图坐标 / 屏幕像素(旁白用) |
name | 第一行显示的说话人,随便写,不必是这个单位 |
text | 正文,自动换行 |
duration_ms | 显示多久;0 = 自动 3 ~ 5 秒 |
key | 世界 / 屏幕气泡的编号,同 key 的新消息顶掉旧的 |
update | 已有同一个气泡时只换文字、不重置计时(流式输出用) |
style | font_px、max_width_px、text_color、bg_color、border_color、tail、side_px、opacity、type_ms、font…… |
同时最多 32 个气泡;每帧开销平均约 0.1 ~ 0.2 ms。
和本地模型对话 POST /api/chat
{
"inst": 16, "unit": "0x14A12614", "name": "山丘之王",
"persona": "你扮演魔兽争霸里的山丘之王穆拉丁,豪爽、爱喝酒。一两句口语,不超过40个字。",
"message": "前面有一群食人魔,我们冲不冲?",
"stream": true
}
返回 {"reply": "...", "first_token_ms": 283, "total_ms": 342},同时这句回复已经出现在那个单位头上。同一个单位会记住最近 6 轮对话。
其它
| 接口 | 说明 |
|---|---|
GET /api/instances | 在跑的游戏 |
GET /api/units?inst=16&mine=true&heroes=true | 单位列表(带中文名、坐标、血量) |
POST /api/clear | 清掉一个或全部气泡 |
GET /api/llm、POST /api/llm | 看 / 改模型配置(base_url、model、max_tokens、temperature) |
POST /api/banter | 农民茶话会:家里的工人按人设轮流吐槽,开局报幕(战况全是真数据) |
POST /api/camtalk | 镜头对白:镜头里的英雄和随从按身份对话 |
POST /api/events | 战况触发:开战、打完、英雄阵亡、升本、被拆……出事了才说 |
本地模型怎么选
在一张 RTX 5090 上实测(5 句游戏台词):
| 模型 | 显存 | 速度 | 一句回复 | 结论 |
|---|---|---|---|---|
| Qwen3.6-35B-A3B(MoE,每次只激活 3B),Q4,关思考 | 20.6 GB | 约 142 token/s | 约 0.3 秒(首字约 0.27 秒) | 推荐:快、中文角色扮演自然 |
| gpt-oss-20b(MXFP4),推理 low | 11.3 GB | 约 280 token/s | 0.3 ~ 0.8 秒 | 显存紧时用,中文略平 |
| Qwen3.6-27B(稠密),Q4 | 17.2 GB | 约 39 token/s | 5.5 秒还在思考 | 不适合实时对话 |
- 速度看「每次激活的参数量」,不看总参数:35B 的 MoE 只激活 3B,比 27B 稠密快 3 ~ 4 倍。
- 必须关掉「思考」:不关的话 token 全花在思考上、一个字都没回。
- 气泡逐字打出约每秒 22 个字,生成速度已经不是瓶颈,真正影响体验的是首字延迟。
让台词「像真的」
给模型的战况一律用真数据(场次、胜负、兵力、库存),并明确「只许用这些事实」。实测不加这条限制时,模型会编出没发生过的战斗。