Godot 网络客户端:把 WebSocket、状态同步和重连边界拆清楚
网络层不应该散在每个玩法脚本里 Godot 可以直接使用 HTTPRequest、WebSocketPeer、MultiplayerAPI 等能力。很多项目早期会在登录页写 HTTP 请求,在战斗脚本里写 WebSocket,在聊天 UI 里直接发消息。
category
网络层不应该散在每个玩法脚本里 Godot 可以直接使用 HTTPRequest、WebSocketPeer、MultiplayerAPI 等能力。很多项目早期会在登录页写 HTTP 请求,在战斗脚本里写 WebSocket,在聊天 UI 里直接发消息。
玩家可以接受挑战失败,但很难接受崩溃后丢十分钟进度。自动存档是保护体验的关键系统,可它也很容易被写坏:保存太频繁会卡顿,保存时机不对会记录危险状态,写入中崩溃会损坏文件,恢复时玩家不知道该选哪个版本。
平台权益是一个很容易被低估的客户端系统。Steam DLC、移动端内购、订阅会员、主机平台附加内容,看起来都是“平台回调告诉我有没有购买”。可真实环境里,回调会延迟,网络会断,玩家会离线启动,平台 SDK 会失败,跨设备状态会不一致。
同伴指令轮盘常见于动作 RPG:按住肩键,时间放慢,选择同伴技能或战术,松手派发指令。体验好时,玩家能在一秒内完成决策;体验差时,轮盘抢输入、目标选错、时间缩放影响 UI、松手后指令没发出去。Godot 实现轮盘并不难,Control 画一个圆形菜单即可。难的是它跨越输入、时间系统、AI、目标选择和战斗反馈。
编辑器里流畅不代表手机上稳定 Godot 在桌面编辑器里跑得很顺,不代表导出到手机也顺。移动端有完全不同的约束:GPU 带宽、纹理格式、内存上限、发热降频、后台生命周期、触控延迟、安装包大小。很多问题只有真机导出后才暴露:第一帧黑屏太久,某些材质变粉,低端机切场景崩溃,玩十分钟后帧率下降。
游戏内商店的购买按钮很敏感。玩家可能用金币、钻石、活动券或多种货币购买道具,商品可能限购、打折、绑定礼包、动态刷新。一次误触、一次价格显示错误、一次失败后 UI 状态没回滚,都可能引发信任问题。Godot 里的商店 UI 可以很快做出来,但购买确认流程不能只是按钮点击后发请求。
运营活动入口看起来是 UI 活:大厅放个按钮,活动开始弹个窗,奖励可领显示红点。可活动一多,问题就来了。签到、限时副本、充值返利、节日兑换、回流任务都想弹窗,都想红点,都想在大厅占位置。玩家一登录,弹窗连环轰炸,红点常亮不消,入口资源没下载完却能点击。
伤害数字和状态提示是战斗反馈的重要组成。数字飞出来,玩家知道攻击命中;绿色治疗出现,玩家知道技能生效;免疫、格挡、暴击、破盾等文字让战斗规则可读。问题是,浮字一多,画面会迅速变乱,性能也会下降。Godot 做浮字通常从 Label 加 Tween 开始,但正式战斗需要更完整的 FloatingTextSystem...
存档问题通常不是写文件,而是几年后还能读 Godot 做单机、买断制、轻联网项目时,本地存档非常关键。很多原型直接把字典转 JSON 写进 ,能存能读,看起来就完成了。真正上线后,问题会变复杂:版本更新后字段变了怎么办,写到一半断电怎么办,玩家改文件怎么办,云存档冲突怎么办,多角色 profile 怎么隔离,调试...
音频系统不只是把声音播放出来。剧情对白、战斗打击、UI 提示、环境声、音乐高潮、队友语音可能在同一秒发生。如果所有声音都按默认音量播放,玩家会听不清重点;如果随便压低某个 Bus,又可能让战斗反馈变弱。音频闪避 ducking 的作用,是让高优先级声音出现时,低优先级声音有节奏地让位。
客户端日志是排查问题的最后证据,但日志不是越多越好。Godot 项目里常见两种极端:开发期到处 ,导出包里什么都没有;或者内测包日志全开,玩家设备上几分钟写出几十 MB,性能和存储都受影响。更稳的方式是把日志当成可观测性系统设计:分级、分类、采样、环形文件、敏感字段过滤、问题发生时打包上报。
对话系统不只是逐字显示文本。剧情游戏、RPG 和任务驱动游戏里,玩家经常需要回看刚才 NPC 说了什么,自己选了哪个选项,某个分支为什么进入当前任务状态。没有历史记录时,玩家一旦手滑跳过或被打断,就只能猜剧情。
Godot UI 不是把 Control 拖到看起来对的位置 Godot 的 Control 系统上手很快,拖按钮、改 Anchor、调 Margin,就能做出界面。问题是如果每个页面都靠手调坐标,到了多分辨率、移动端安全区、语言变长、手柄焦点、主题换肤时,界面会不断破。
城镇和营地需要热闹感。路人走动、商贩招呼、卫兵巡逻、同伴闲聊,都会让世界更可信。但如果每个 NPC 都每帧寻路、检测玩家、播放复杂动画、更新头顶 UI,低端设备很快顶不住。热闹不等于每个路人都用主角级成本运行。
角色外观系统常常先从一个简单需求开始:玩家能换衣服、换武器、调颜色。真正做进客户端后,它会牵出模型组合、材质实例、骨骼挂点、资源加载、拍照预览、移动端性能和存档同步。尤其预览界面,如果每次点击外观都同步加载模型,玩家会觉得整个商城都在卡。Godot 适合做这类系统,但需要把加载、组合、染色、缓存和回滚统一起来。
游戏内邮件看起来是普通列表:标题、正文、附件、领取按钮。真正上线后,它会承载补偿、活动奖励、客服处理、系统通知和运营公告。邮件一旦和奖励绑定,就不能只当作文本 UI。已读、未读、可领、已领、过期、领取中、领取失败,这些状态必须清楚,否则玩家会觉得奖励丢了。
移动端 UI 最容易被忽略的细节,是屏幕边缘并不都可用。刘海、圆角、系统手势条、状态栏、横竖屏切换、折叠屏比例,都会影响按钮是否可点、文字是否被挡、HUD 是否贴边。Godot 的 Control 锚点能做响应式布局,但项目需要一层 SafeAreaLayoutService,把平台安全区转成 UI 可使用的约束。
输入系统先抽象意图,再处理设备 Godot 的 InputMap 很适合做动作映射: 、 、 、 。但很多项目仍然在脚本里直接判断键盘按键、鼠标按钮或屏幕触点。这样一开始很快,后来要支持手柄、移动端、键位重绑定、无障碍设置时,就会非常痛苦。
移动端输入如果只靠 和几个控件回调,很快就会变得混乱。按钮需要点击,背包需要长按,地图需要双指缩放,角色需要虚拟摇杆,列表需要滑动,战斗还要识别轻扫。每个控件自己判断手势,冲突就不可避免。我更倾向于在 Godot 项目里建立统一的 GestureRecognizer,在原始触摸事件和业务系统之间做识别、仲裁和派发。
世界地图标记看起来只是把图标画在地图上,实际会牵涉任务、探索、传送点、商店、采集点、玩家自定义标记、活动入口和多人队友位置。图标一多,地图就会变成噪音;筛选一多,玩家又找不到关键目标;追踪状态如果和任务系统不同步,HUD 和地图会互相矛盾。