1. 快速接入
问 1001: 如何快速接入游戏?
- 快速接入 QuickStart-Android Demo ,复用SudMGPWrapper;
- 快速接入 QuickStart-iOS Demo ,复用SudMGPWrapper;
- 快速接入 QuickStart-Flutter Demo;
- 快速接入 hello-sud-java 服务端 Demo (访问不了代码仓库,请联系SUD添加github账号);
问 1002: 如何快速定位和解决接入过程中遇到的问题?
- 请检查接口输入参数是否正确(mgId是64bit类型);
- 请查看Android Studio 或 XCode 控制台日志信息,错误码字段result_code、sdk_error_code、retCode数值;
- 请将问题描述、视频、截图、控制台日志(文件)等信息,发送给我们的技术支持同学,协助您分析和解答;
问 1003: 我的App是否可以集成SudMGP SDK
只要在App的 UI 框架中能嵌入原生View, 您的App就能直接集成SudMGP SDK
问 1004: 有lite版SudMGP-lite SDK 和 标准版SudMGP SDK, 应该用哪个?
lite版支持部分游戏,标准版支持所有游戏。 可根据App集成的游戏选择SudMGP SDK版本:各端SDK对游戏支持情况列表
问 1005: HelloSudPlus体验demo下载(展示多业务场景)
问 1006:Android SDK上架Google Play
需要替换成符合Google Play政策的SDK。接口不变,只是替换SDK依赖,请访问:SudMGP-Android
2. SudMGP接口
问 2001: APP调用SudMGP SDK 接口能在非UI/Main线程吗,SudMGP回调APP是在哪个线程?
- APP调用SudMGP SDK任何接口,都必须在 UI/Main 线程发起调用;
- SudMGP回调APP,都是在 UI/Main 线程回调;
- SudMGP负责转线程,简化APP接入逻辑;
问 2002: 关于APP调用notifyStateChange接口,listener回调作用吗?
- notifyStateChange,是APP状态通知给小游戏;
- ISudListenerNotifyStateChange回调只表示APP状态通知到了小游戏,不表示小游戏执行完成状态通知的逻辑代码(比如:游戏业务逻辑网络请求),接入排查连通性,可以传null;
- 不要在回调里面写逻辑;
- 如果想知道调用结果是否失败,可以接 App通用状态操作结果错误码, mg_common_app_common_self_x_resp;
问 2003: 关于游戏回调APP时,ISudFSMStateHandle handle参数?
- 有ISudFSMStateHandle handle的地方,APP必须调用handle.success,否则会导致C++层回调对象内存泄漏;
- 游戏向App 获取xx信息,则APP需要handle.success带具体参数;
void onGetGameViewInfo(ISudFSMStateHandle handle, String dataJson); void onGetGameCfg(ISudFSMStateHandle handle, String dataJson);
- 游戏向App 通知状态信息,则APP只需要handle.success("{}");
void onExpireCode(ISudFSMStateHandle handle, String dataJson); void onGameStateChange(ISudFSMStateHandle handle, String state, String dataJson); void onPlayerStateChange(ISudFSMStateHandle handle, String userId, String state, String dataJson);
问 2004: SudMGP是否支持同时运行两个游戏实例?
- 不支持同时运行两个游戏实例;
- SudMGP的loadMG和destroyMG必须配对使用;
- SudMGP负责转线程,简化APP接入;
3. 功能实现
问 3001: 如何隐藏游戏背景,显示APP自定义背景?
- 隐藏游戏Loading时的背景:APP调用SudMGP.loadMG之前,设置SudMGP.getCfg().setShowLoadingGameBg(false);
- 隐藏游戏场景的背景(游戏大厅):APP在ISudFSMMG.onGetGameCfg 回调,设置 ui.game_bg.hide=true;
- SudMGP SDK 最低版本v1.1.46.xx
下载 SudMGP-iOS
问 3002: 如何隐藏游戏橙色Loading进度条,APP自定义Loading进度条?
- APP调用SudMGP.loadMG之前,设置SudMGP.getCfg().setShowCustomLoading(true);
- 加载进度通知ISudFSMMG::onGameLoadingProgress(int stage, int retCode, int progress);
- 加载失败,APP调用重试接口ISudFSTAPP::reloadMG();
- SudMGP SDK 最低版本v1.1.52.xx
下载 SudMGP-iOS
问 3003: 游戏View和APP的UI层级关系,游戏安全区(交互操作)?
- 游戏View,当成是Android 和 iOS 原生View;
- 游戏View,可以全屏,也可以固定尺寸大小;
- 游戏View,大小铺满APP给的父View(GameViewContainer);
- 游戏通过ISudFSMMG的onGetGameViewInfo回调,获取游戏安全区(交互操作)
问 3004: 游戏UI元素是否支持隐藏,按钮点击事件是否支持拦截?
- 支持隐藏游戏UI元素; 具体配置参考 onGetGameCfg
- 支持拦截按钮点击事件; 具体配置参考 onGetGameCfg
问 3005: 游戏是否支持APP自定义实现加入游戏、开始游戏等逻辑功能?
- 支持;
- 支持隐藏游戏UI元素,APP可以实现对应按钮; 具体配置参考 onGetGameCfg
- 支持拦截按钮点击事件; 具体配置参考 onGetGameCfg
- APP可以通过ISudFSTAPP的notifyStateChange接口,实现加入游戏、开始游戏等逻辑功能; 具体示例:开始游戏按钮
第一步 onGetGameCfg(IFSMStateHandle handle, String dataJson)
data = {
"gameMode":1, // 每个游戏默认模式是1,不填是1
"ui":{
"start_btn": { // 开始游戏按钮
"custom": true,
"hide": false
}
}
}
handle.success(data);
第二步 接onGameStateChange mg_common_self_click_start_btn状态回调
第三步 APP判断是否开始游戏,允许开始则调用ISudFSTAPP notifyStateChange接口发送app_common_self_playing状态
问 3006: 游戏是否支持多语言本地化,不支持的语言是否支持提供翻译添加?
- 支持多语言本地化;
- 支持提供翻译添加,需要联系Sud商务;
- SudMGP.loadMG的language参数;例如:zh-CN、en-US;
问 3007: APP什么时候可以调用游戏ISudFSTAPP.notifyStateChange接口?
- APP收到回调ISudFSMMG.onGameStarted后,可以调用ISudFSTAPP.notifyStateChange接口;
- onGameStarted,表示游戏已开始(游戏长连接建立完成);
- 用户在游戏的角色状态转化,只能从"当前状态" 转换到 "邻近状态";
问 3008: 每一局游戏如何透传APP自定义参数和自定义查询Key?
- APP调用ISudFSTAPP.notifyStateChange(state, dataJson)
state=app_common_self_playing 和 dataJson.isPlaying=true
{ "isPlaying": true, // true 开始游戏,false 结束游戏 "reportGameInfoExtras": "透传参数", // string类型,Https服务回调report_game_info参数,最大长度1024字节,超过则截断(2022-01-21) "reportGameInfoKey": "透传参数key" // string类型,最大长度64字节,接入方服务端,可以根据这个字段来查询一局游戏的数据 }
4. 兼容性解决方案
问 4001: 如何解决Android软键盘弹起时,导致游戏View整体上移?
- AndroidManifest.xml android:windowSoftInputMode="adjustResize";
- 在ISudFSMMG回调onGameStarted时,调用setSoftInputMode设置;
public void onGameStarted() { getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); }
问 4002: 在iOS上,退出游戏房间时,同时调用RTC的destroy和SudMGP SDK的destroyMG,有时会出现rtc与openal的不兼容问题,堆栈中会出现AURemoteIO和OpenAL符号
有的小游戏使用openAL播放音效,底层封装AudioUnit混音,如果RTC的destroy方法异步调用[AVAudioSession setCategory:error:]方法,会使AudioUnit线程去copy无效的音频buffer,出现rtc与游戏音效底层openal的不兼容问题。 在调用RTC的destroy方法后,同步调用[AVAudioSession setCategory:error:],能够解决这个问题,category推荐传系统默认SoloAmbient
问 4003: Android SDK需要的OkHttp版本说明
v1.4.1.1195及以上版本,需要OkHttp库的最低版本是3.11.0
v1.3.2.1154到v1.4.0.1191版本,需要OkHttp库的最低版本是3.14.0
v1.3.2.1154以下版本,需要OkHttp库的最低版本是3.11.0
问 4004: 使用Maven集成Android SDK时,偶尔报Could not find SudMGP-x.x.x.x.jar的问题
SudMGP SDK以aar形式存在,在使用镜像Maven时,偶尔发生找不到jar包就报错。 有两种解决方法: 一是屏蔽镜像Maven, 二是引入SDK时,在tech.sud.mgp:SudMGP:x.x.x.x 后追加@aar
5. 游戏个性化状态
问 5001: 狼人杀,如何实现语音版本(天黑请闭眼,几号玩家发言)?
一、APP根据下面两个状态,无脑开启和关闭RTC的推流和拉流(不这么执行,可能会出现作弊情况)
- mg_common_self_microphone, "isOn": true // 麦克风开关状态 true: 开(APP开启RTC推流);false: 关(APP关闭RTC推流)
- mg_common_self_headphone "isOn": true // 耳机(听筒,喇叭)开关状态 true: 开(APP开启RTC拉流);false: 关(APP关闭RTC拉流)
二、判断APP的麦克风能不能点击,建议条件1和条件2为真才能点击,不能点击给个toast提示:
条件1 mg_common_game_state gameState=2
条件2 mg_common_self_microphone isOn=true(该玩家自己发言了,但是玩家可以选择闭麦)
问 5002: 你画我猜,如何区分谁作画,谁回答?
- 选词中状态
- 作画中状态
- 显示错误答案状态
- 显示总积分状态
- 本次获得积分状态
6. iOS端游戏bgm问题与解决方案
问 6001:游戏开启后无声音?
SudMGP SDK默认会激活AVAudioSession和修改AVAudioSessionCategory。如果要限制SDK对Audio Session的控制权限, 请调用SDK接口:
/// v1.3.6以前版本 [SudMGP autoSetAudioSession:NO]; /// v1.3.6及以后版本,拆分两个接口独立控制,根据需求自行结合使用 /// 关闭SDK控制session [[SudMGP getCfg]setEnableAudioSessionActive:NO]; /// 关闭SDK控制category [[SudMGP getCfg]setEnableAudioSessionCategory:NO];
此时,由App和其它第三方组件负责对Audio Session进行操控。可能会导致游戏bgm无声。请勿在小游戏运行期间,关闭AVAudioSession的活动状态。
确保三方SDK如RTC厂商SDK在语音层面上下麦或者退出语音引擎时不要修改AVAudioSession为未激活态,常见可控制rtc厂商修改AVAudioSession状态的控制开关如下:
Zego即构:
/// 添加配置audio_session_do_nothing:true,可以禁止退出RTC房间关闭AVAudioSession engineConfig.advancedConfig = @{@"audio_session_do_nothing": @"true"}; [ZegoExpressEngine setEngineConfig:engineConfig];
Agora声网:
/// 初始化引擎时,配置AgoraRtcEngineKit的方法配置该参数:AgoraAudioSessionOperationRestrictionDeactivateSession - (void)setAudioSessionOperationRestriction:(AgoraAudioSessionOperationRestriction)restriction;
NERTC网易云信:
/// 加入房间前,配置NERtcEngine的方法配置该参数:kNERtcAudioSessionOperationRestrictionDeactivateSession - (int) setAudioSessionOperationRestriction:(NERtcAudioSessionOperationRestriction)restriction;
AliRtc阿里云:
/// 配置AliRtcEngine的方法配置该参数:AliRtcAudioSessionOperationRestrictionDeactivateSession - (int)setAudioSessionOperationRestriction:(AliRtcAudioSessionOperationRestriction)restriction;
其它RTC厂商:
若存在期间禁止AVAudioSession的情况发生时,请咨询沟通RTC厂商寻求解决办法。
问 6002:静音按钮关闭后无游戏声音?
- 游戏SDK默认会将AVAudioSession的category设置为AVAudioSessionCategoryAmbient模式,此模式受控于静音按钮,如需在静音状态下仍旧有声音,则需App在游戏加载后,例如在onGameStarted中,将category改为:AVAudioSessionCategoryPlayback。
问 6003:应用进入后台后,后续RTC没声音了
当游戏进入后台,游戏会尝试暂停session,此时,在RTC场景下可能出现两种情况:
- 如果进入后台前,RTC存在声音播放,则进入后台时,游戏暂停session会失败,游戏声音停止,RTC自身声音继续播放。部分RTC如声网,可能出现声音从耳麦出来,这取决于RTC或者应用外部去定向声音输出通道,游戏本身不会对声音通道做任何定向输出。
- 如果进入后台前,RTC不存在声音播放,则进入后台时,游戏暂停session会成功并发起系统通知,游戏声音停止,后续RTC播放声音会无声。此种情况下如果后续让RTC自身需要播放声音,则需要重新在有流时激活session。
7. 内嵌游戏资源包使用
问7001:怎么在工程中使用内嵌包?
步骤一. 将内嵌包xxxx.sp放入工程的assets目录
Android: 将内嵌包放在资源目录assets目录下即可
iOS: 在工程目录下创建assets目录, 将内嵌包放在assets目录下,并且将assets目录或者内嵌包文件添加到XCode工程
步骤二. 调用addEmbeddedMGPkg接口,添加游戏内嵌包
/// iOS
[[SudMGP getCfg] addEmbeddedMGPkg:1583284410804244481 mgPath:@"xxxx.1.0.0.1.sp"];
/// Android
SudMGP.getCfg().addEmbeddedMGPkg(1583284410804244481, "xxxx.1.0.0.1.sp");
注意事项:
- 上述方法调用在loadMG之前调用即可。
- 嵌入成功现象:首次加载游戏时,进度40%直达80%。
- 内嵌包文件名必须包含版本号。Sud提供的游戏内嵌包会包含版本号,如果是集成方自己准备的内嵌包,请和Sud联系获得所配置游戏的当前版本号,将版本号加入到内嵌包文件名中。
8. 关于iOS企业签名导致游戏加载失败问题
问 8001:iOS端企业签名的ipa包出现运行游戏报错无法加载怎么办?
SudMGP内部下载资源默认启动了后台下载模式,此模式下,如果企业签名的IPA包的embedded.mobileprovision签名文件中application-identifier与应用本身bundleId不匹配时,应用无权限访问下载到的资源路径导致游戏加载失败。
选择其中一种处理方式:
- 确保签名时application-identifier与应用本身bundleId匹配。
- 关闭后台下载模式:
[[SudMGP getCfg] setBackgroundMode:NO];
9. Android Release包无法加载游戏
问 9001:Android Debug包可以加载游戏,Release包无法加载游戏的问题
Android Demo下载地址:HelloSud
同一份代码,Debug包可以加载游戏,Release包无法加载的情况,请按照以下步骤检查混淆配置
1.代码混淆:
在Demo:project/SudMGPWrapper/consumer-rules.pro文件中已定义好混淆配置
-keep class tech.sud.mgp.SudMGPWrapper.** {*;}
集成时导入SudMGPWrapper模块,此配置会自动应用到项目中,无需做额外的工作
如果修改了项目中SudMGPWrapper模块内代码的包名,请"-keep class xx.xx.xx.** {*;}"
新的包名
原因是?,比如:tech.sud.mgp.SudMGPWrapper.model.GameViewInfoModel
在Demo中,会使用Gson序列化该类,将安全区状态发送给游戏,如若混淆了该类,则json数据字段不对,游戏无法解析
2.资源混淆:
如果项目中使用了资源混淆:AndroResGuard
请添加相应的白名单配置,文档链接:QuickStart
文档内搜索"白名单"即可定位
10. SDK日志存储路径
1.Android日志存储路径在:
/externalStorage/emulated/0/Android/data/[应用包名]/files/SudMGPLogs
可通过手机“文件管理”的手机存储,将“Android/data/[应用包名]/files/SudMGPLogs”目录下的文件分享到社交APP、邮箱
2.iOS日志存储路径在:
/Library/Caches/SudMGPLogs