7月31日同步更新

This commit is contained in:
MCNeteaseDevs
2025-07-31 17:53:14 +08:00
parent f5c6bdba2e
commit cf061270d3
799 changed files with 27437 additions and 494 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,45 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/kaifaliucheng.371ad651.png
hard: 入门
time: 5分钟
selection: true
---
# 开发流程说明
从入驻到上线可分为四个阶段,详见下图:
![img](./images/kaifaliucheng.png)
### 准备阶段
此阶段主要是一些必要的准备首先需要成为一名开发者开发者需要申请网络服入驻通过后可提供固定IP和公钥获取开发机。拥有开发机之后可进入开发阶段。
### 开发阶段
此阶段依赖**开发机**,进行服务器部署、游戏内容开发等操作。开发完毕,可搭建审核服。同时在开发者平台-PE内容管理-PE网络游戏管理中选择发布游戏填写对应信息提交审核官方人员会在**10个工作日**内予以审核并给到审核结果。提审通过后,将进入审核阶段。
### 审核阶段
游戏内容经官方人员审核通过后,会依据网络游戏情况发放**正式物理机**,用于正式环境的网络游戏搭建。开发者搭建完成后,同样在开发者平台-PE内容管理-PE网络游戏管理中选择发布游戏即可提交审核并通过后游戏即可上线。
### 上线阶段
此阶段需使用正式物理机,以保证服务器性能。除了日常维护,服主也可申请上新、日常推荐,增加游戏曝光度。

View File

@@ -0,0 +1,61 @@
---
front:
hard: 入门
time: 15分钟
---
# Apollo框架
## 框架介绍
![](./images/apollo_framework.png)
- **DB**是全局存储系统所有游戏服共享可以是redis、mysql或mongodb等。其中redis用于缓存临时数据比如玩家在线状态、当日在线时长等mysql和mongo用于持久化存储游戏数据。开发者根据需求自选。
- **proxy**是代理服,功能包括消息的加密和解密,消息的压缩和解压缩,登录认证和消息转发。它保持客户端到服务端的连接。 开发者不能对proxy进行开发。
- **game**是游戏服提供游戏逻辑功能一个在线玩家只存在于一个game或lobby中。 开发者在game上进行游戏玩法开发比如实现酷跑游戏、射击游戏、战斗游戏。
- **lobby**是大厅服,提供大厅各项功能。 开发者在lobby开发大厅的功能比如提供NPC选服入口提供战斗副本入口。
- **master**是控制服用于管理其他服是全服单点对外提供http服务。http服务是运营指令gm指令入口。 开发者可以在master开发运营指令比如发奖励指令、禁止发言指令。下面通过禁言指令需求介绍master功能
- 需求:某玩家言词不当,需要禁止他聊天。
- 实现在master添加禁言指令。开发者使用http给master发送禁言请求master会把禁言信息记录到db然后给玩家所在服务器发消息禁止玩家发言。玩家下次登陆时从db中读取禁言信息判断是否还可以聊天。
- **service**是功能服用于提供分布式单点服务。开发者可以在service开发公会、全服boss、全服匹配等功能。下面通过全服匹配需求介绍service功能
- 需求存在lobby1和lobby2两个大厅服两个大厅服内玩家要按照等级、战力等属性进行匹配进入同一个副本游戏。
- 实现玩家申请匹配时lobby1或lobby2向service申请匹配service维护一个匹配队列记录所有正匹配玩家service会定时取出队列玩家按照等级和战力匹法将匹配后玩家分配到指定副本游戏。
## 使用示例
通过一个简单网络游戏需求介绍Apollo框架的使用。
### 需求
玩家可以在大厅签到领取奖励然后体验两种游戏起床战争和对战pvp另外游戏提供禁言指令。对战pvp要求一场战斗最多两个玩家玩家等级最多相差2。
### 实现
下面介绍开发者需要开发内容:
- master mod实现禁言指令。master接收禁言消息并将它记录到mysql然后通知玩家所在服务器告知禁止玩家聊天。
- service mod实现全服匹配。service维护匹配队列记录所有正在匹配玩家接着按照玩家等级匹配将匹配成功的两个玩家分配到pvp服
- game mod分别实现起床战争和对战pvp接收master禁言消息禁止玩家聊天登陆读取玩家数据判断是否禁言。
- lobby mod
- 提供签到功能使用mysql记录玩家的物品和签到奖励时间
- 提供两个NPC点击NPC进入起床战争游戏或向service申请匹配进入对战pvp
- 接收master禁言消息禁止玩家聊天登陆读取玩家数据判断是否禁言。
### 功能执行过程
说明玩家体验游戏过程中引擎开服工具框架和开发者mod分别完成的功能。
#### 签到过程
1. 玩家登陆lobby引擎会将玩家分配到lobby。
2. 玩家领取签到奖励开发者lobby mod完成签到功能。
#### 禁言过程(假设玩家在lobby1)
1. 开发者给master发送http请求引擎会接收http请求然后将请求传递给开发者master mod
2. 禁止玩家聊天开发者master mod处理禁言消息开发者game/lobby mod实现禁言功能
3. http请求返回开发者master mod将执行结果告知引擎引擎将结果返回给请求发起方
#### 进入起床战争
1. 玩家登陆进入lobby引擎会将玩家分配到lobby。
2. 玩家点击NPC玩家切服到起床战争的game开发者lobby mod实现NPC和切服功能
3. 体验起床战争开发者game mod实现起床战争玩法
4. 游戏结束玩家退回到lobby开发者game mod将玩家切服到lobby
#### 进入对战pvp
1. 玩家A和玩家B登陆到lobby引擎会将玩家分配到对应lobby
2. 玩家A和玩家B点击NPC申请匹配开发者lobby mod向service申请匹配开发者service mod完成匹配将玩家分配到战斗pvp游戏服
4. 体验pvp战斗开发者game mod实现pvp战斗玩法
4. 游戏结束玩家退回到lobby开发者game mod将玩家切服到lobby

View File

@@ -0,0 +1,158 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/image071.96fa4242.png
hard: 入门
time: 20分钟
---
# 服务器Mod
## Mod类型
服务器Mods通常由控制服Mod功能服Mod大厅服Mod与游戏服Mod等组成各种类型的Mod概念如下
- 控制服Mod包含控制服(master)的developer_mods目录下所有mod。
- 功能服Mod包含功能服(service)的developer_mods目录下所有mod。
- 大厅服Mod包含大厅服的 behavior_packs、resource_packs、developer_mods目录下所有的mod以及worlds地图存档
- 游戏服Mod包含游戏服的 behavior_packs、resource_packs、developer_mods目录下所有的mod以及worlds地图存档
一个游戏服Mod的**标准目录格式**如下:
![](./images/image071.png)
以下内容涉及较多代码部分,建议在入门阶段暂时跳过。
------
## developer_mods
服务端加载的mod目录不会被传送到客户端。
下面以neteaseAnnounce为例介绍其目录结构
neteaseAnnounceDev
netease_require.json
neteaseAnnounceScript
__init__.py
announceConsts.py
announceServerSystem.py
modMain.py
timermanager.py
mod.json
|文件/文件夹|解释|
|--------|----------|
|neteaseAnnounceDev| 顶层neteaseAnnounceDev表示mod的名字第二级neteaseAnnounceScript表示行为包的目录开发者从从该目录开始import module比如import neteaseAnnounceScript.announceConsts as announceConsts |
|`__init__.py`| 是python module的标识表示这是一个可以import的module同时也可以做一些初始化的操作,内容可为空,但是文件必须有。 |
|announceConsts.py| mod中的一些宏定义|
|announceServerSystem.py|mod业务逻辑|
|modMain.py|该文件名称不可以更改用来初始化我们的Mod具体使用参考<a href="../../20-玩法开发/13-模组SDK编程/2-Python脚本开发/0-脚本开发入门.html#modmain-py是什么" target="_blank">mod开发简介</a>|
|timermanager.py|实现了一个定时器提供了一次性定时器和循环定时器当前ModSDK中已经有实现相同功能的组件不再需要自己实现|
|netease_require.json| 用于控制服务器Mod加载顺序的配置文件非必须具体内容见《1-9 控制服务器Mod加载顺序的办法》|
|mod.json| 用于配置mod的具体功能实现细节行为的配置文件非必须|
developer_mods和behavior_packs区别
- developer_mods控制服务端行为behavior_packs控制客户端行为。
- behavior_packs会下载给客户端developer_mods不会。
- developer_mods可以使用Server Mod SDK全部接口和MOD SDK中服务端相关接口behavior_packs使用MOD SDK中客户端相关接口。
- behavior_packs必须包含manifest.json文件且需要在地图目录下world_behavior_packs.json文件中配置pack id和version。
developer_mods支持多个mod每个mod对应一个目录下面是neteaseAnnounce和neteaseAlert两个mod的目录结构
neteaseAnnounceDev
netease_require.json
neteaseAnnounceScript
__init__.py
announceConsts.py
announceServerSystem.py
modMain.py
timermanager.py
mod.json
neteaseAlertDev
neteaseAlertScript
__init__.py
alertConst.py
alertServerSystem.py
modMain.py
mod.json
## resource_packs
- 存放客户端资源
- 资源版本信息存放在manifest.json
```
{
"format_version": 1,
"header": {
"description": "By tnm",
"name": "tnm_glove_pve",
"uuid": "1c850d23-64f4-46be-aec0-16c8e4618072",
"version": [0, 0, 1]
},
"modules": [
{
"description": "By tnm",
"type": "resources",
"uuid": "637ff742-7003-4a8b-8d99-722a1b704f12",
"version": [0, 0, 1]
}
]
}
```
- 并非所有resource_packs都会被客户端下载
- 需要将`manifest.json`配置header中uuid配置到worlds/level/`world_resource_packs.json`中才会被客户端下载
- `world_resource_packs.json`内容如下:
```python
[
{
"pack_id" : "1c850d23-64f4-46be-aec0-16c8e4618072",
"version" : [ 0, 0, 1 ]
}
]
```
## behavior_packs
- 存放客户端MOD
- manifest.json& world_behavior_packs.json配置与resource_packs类似
- behavior_packs里只允许有一个目录如果有多个则只有第一个会被使用请按*behavior格式命名大小写不敏感
- `*behavior`目录内脚本需要存放在*scripts目录内且只允许有一个
- `*behavior`目录内需包含版本信息配置`manifest.json`
## worlds
- 只允许有一个子目录如demo中的level
- 目录名作为地图名称,不允许使用中文
- 不要忘了配置`world_behavior_packs.json`等两个json
一个示例的目录结构如下:
worlds
level
db
level.dat
levelname.txt
world_behavior_packs.json
world_resource_packs.json
|文件/文件夹|解释|
|--------|----------|
|worlds| 存放服务器地图目录,名字不可以更改|
|level| 存放一个地图存档目录,目录名也就是地图名|
| db| 地图存档目录|
| level.dat| 存储关于地图的全局信息|
|levelname.txt|地图的名字|
|world_behavior_packs.json|配置客户端需要下载的behavior mods|
|world_resource_packs.json|配置客户端需要下载的resource mods|

View File

@@ -0,0 +1,115 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/bushujieshao.32a5d8c3.png
hard: 入门
time: 15分钟
---
# 部署
任何针对服务器配置的修改或者服务器mod的修改仅保存在本地。若需要在服务器中生效需要进行部署操作。开发、审核、上线阶段都需要部署操作。
MCStudio部署网络服有多种方式包含智能部署重新部署热更三种。另外开发阶段的部署跟审核、上线阶段的部署又有设置上的区别。
简单起见,这里先介绍最常用的一种情况:开发阶段执行智能部署。
在开发阶段任何服务器配置或者服务器mod的修改之后可直接点击部署按钮将修改同步到开发机中。
![](./images/bushujieshao.png)
以下内容涉及较多进阶知识,建议在入门阶段暂时跳过。
------
## 智能部署
网络服开发页面的部署按钮默认采取智能部署方式,总是尝试采取最快最低成本的更新方式,使修改的代码生效。
通常在开发阶段,总是使用智能部署就可以了。
常用的配置包括修改服务器数量修改Apollo大小版本新增一种类型的大厅服/游戏服等。
Apollo网络服中的各种配置可以一次性修改部署会自动根据配置的变化选择最优的部署方式。
如果网络服配置修改了**全局设置**,如控制服、功能服、数据库或更多配置,**智能部署**会触发**重新部署**,重新部署前会关闭当前的所有服务器并清空该网络服的文件,再进行部署。
通常情况下,只修改大厅服/游戏服/代理服,则不会触发重新部署,而是采取**滚动更新**方式应用到服务器上。
**滚动更新**使用最新Mod代码启动一批新服来接管需要更新的旧服务器旧服务器将采取**优雅停机**的方式退出
![](./images/gundonggengxin.png)
**滚动更新注意事项**假如配置中选择了【保存地图】那么需要两次滚动更新才能安全更新对应服务器上的Mod第一次更新选择删除服务器让目标服务器正常关闭并上传地图文件第二次更新新建服务器使用相同的配置参数并且选择使用【服务器最新地图】。
**优雅停机**:正在服务器游玩的玩家不受影响,但不会再分配新玩家进入,当所有玩家退出后,旧服自然停机
**样例**修改Mod目录内的游戏服gameA的代码并保存点击网络服开发的部署按钮则MCStudio会滚动更新所有gameA游戏服并移除本地电脑中的gameA的客户端脚本缓存
**注意**如果开发者正在gameA游戏服中则开发者必须退出后重新登陆gameA游戏服放可验证新的代码
![](./images/bushujieshao.png)
## 重新部署
在网络服开发分页,选中网络服的更多 => 重新部署可以显式指定MCStudio使用重新部署来应用修改。
重新部署会关闭当前的所有服务器并清空该网络服的文件包括日志再重新上传Mod进行部署。
![](./images/chongxinbushu.png)
## 热更
热更是指不停服更新服务器部分的代码,它的执行有以下前提:
- 修改的Mod内容**只包含运行在服务端部分**的代码,即**developer_mods**里的代码修改
- **只修改了函数内实现**
如果满足上述条件,则可以选中网络服的更多 => 热更来应用新的服务器代码
热更可以避免客户端被踢出,更新应用的速度也比滚动更新和重新部署更快速,在开发期提升调试的效率,在正式运营时也可以作为问题的修复手段
**样例**开发者在gameA游戏服验证Mod功能时发现异常通过修改游戏服gameA的developer_mods里的代码进行修复或增加日志用于排查问题保存后点击更多 => 热更则MCStudio会上传更新的代码到gameA游戏服并执行服务端代码热更操作开发者无需退出gameA即可继续验证内容
![](./images/hotfix.png)
## 开发阶段部署设置
- 开发阶段部署需要关闭验证、关闭崩溃自动拉起、关闭运营数据。
- 开发阶段部署需要开启打包代码、开启打印调试代码。
![1591081377849](./images/kaifabushu.png)
## 审核阶段部署设置
- 完成开发后可进行提审,以便申请正式物理机。您需要在发布界面的开发者平台上新建一个正式网络服项目。
- 新建好正式网络服项目并设置对应的游戏ID
- 审核阶段部署需要关闭验证、关闭崩溃自动拉起、关闭运营数据。
- 审核阶段部署需要开启打包代码、开启打印调试代码。
![1591081377849](./images/shenhebushu.png)
## 上线阶段部署设置
- 通过网络服的demo提审后会发放正式物理机您需要在发布界面的开发者平台上新建一个正式网络服项目。
- 新建好正式网络服项目并设置对应的游戏ID
- 上线部署需要关闭打印调试代码
- 上线部署都需要开启打包代码
- 上线部署需要开启认证和崩溃自动拉起,同时也需要开启监控运营数据
![1591081377849](./images/shangxianbushu.png)

View File

@@ -0,0 +1,29 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/lingdichajian.9a30c0b7.png
hard: 入门
time: 15分钟
---
# 网络服插件
### 什么是插件
在Apollo开服工具中插件是一系列网络服Mod的集合这些网络服Mod集合共同实现比较独立完整的系统功能。每个插件具有配套的**API**和**运营指令**,便于开发者在开发阶段产出更丰富的功能,也便于在运营阶段查询游戏数据。
例如开发者调用了领地插件,则可以在游戏中直接打开界面,操作创建领地、权限管理等相关功能,无需关注实现的细节部分。
![](./images/lingdichajian.png)
如果需要调整官方插件功能则可以使用领地插件提供的API。
![](./images/lingdichajian1.png)
### 官方插件概述
目前官方具有30多个插件这些插件会**长期维护**,开发者不用担心版本升级导致插件失效。另外官网也会持续拓展插件库的**数量**与**功能**,让开发者能便捷开发网络服。
![](./images/chajian1.png)
![](./images/chajian2.png)

View File

@@ -0,0 +1,192 @@
---
front:
hard: 进阶
time: 20分钟
---
# Mod到网络游戏Mod入门
这篇教材将带领有Mod基础的开发者进入网络游戏Mod开发教材讲述如何将“脚本开发入门”中介绍的脚本Mod转化成网络游戏Mod引导开发者入门网络游戏Mod。本教材要求开发者已经申请到了开发机按照“网络游戏入驻”流程申请且会使用部署工具参考“使用部署工具”已经阅读“脚本开发入门”
网络游戏Mod主要由服务端Mod和客户端Mod组成。客户端Mod包含行为包和资源包它运行在玩家手机上可以处理界面交互、特效、entity 行为等逻辑只能使用Mod SDK客户端组件和事件。服务端Mod运行在linux机器上它可以从数据库存取玩家数据实现玩家之间交互可以使用Apollo SDK所有功能、Mod SDK服务端组件和事件。下面介绍如何将Mod转化为网络游戏Mod
## Mod转化成网络游戏Mod
1、创建tutorialApolloMod文件夹作为网络游戏Mod的根目录然后创建behavior_packs、resource_packs、worlds、developer_mods四个文件夹。
![img](./images/image-20210127172516895.png)
2、打开“入门脚本模板”的目录可以找到“tutorialBehaviorPack_xxx”文件夹和“tutorialResourcePack_xxx”文件夹
![image-20210127171721936](./images/image-20210127171721936.png)
3、把“tutorialBehaviorPack_xxx”文件夹拷贝到behavior_packs目录下重命名为tutoriaBehavior
![image-20210128145729718](./images/image-20210128145729718.png)
把“tutorialResourcePack_xxx”文件夹拷贝到resource_packs目录下重命名为tutorialResource
![image-20210128145754405](./images/image-20210128145754405.png)
4、developer_mods新建tutorialDev文件夹然后把“tutorialBehaviorPack_xxx”文件夹里面的tutorialScripts复制到tutorialDev目录下
![image-20210127172754284](./images/image-20210127172754284.png)
5、在worlds目录下创建level文件夹里面创建world_behavior_packs.json文件和world_resource_packs.json文件
![image-20210127172928809](./images/image-20210127172928809.png)
打开“tutorialBehaviorPack_xxx”文件夹里面的manifest.json文件把header层级下的uuid、version字段对应值配置到world_behavior_packs.json文件中
![image-20210128145952235](./images/image-20210128145952235.png)
打开“tutorialResourcePack_xxx”文件夹里面的manifest.json文件把header层级下的uuid、version字段对应值配置到world_resource_packs.json文件中
![image-20210128150008665](./images/image-20210128150008665.png)
## 一个游戏服Mod的目录结构
我们以tutorialApolloMod为示例介绍一个游戏服Mod目录结构
tutorialApolloMod
behavior_packs
tutorialBehavior
developer_mods
tutorialDev
tutorialScripts
resource_packs
tutorialResource
worlds
level
world_behavior_packs.json
world_resource_packs.json
| 文件/文件夹 | 解释 |
| ------------------------- | ------------------------------------------------------------ |
| tutorialApolloMod | 游戏服Mod根目录 |
| behavior_packs | 存放客户端行为包,可以包含多个行为包 |
| tutorialBehavior | 行为包 |
| developer_mods | 存放服务端Mod这些Mod只会运行在服务器不会传送给客户端 |
| tutorialDev | 服务端Mod |
| tutorialScripts | python脚本的根目录该目录的脚本会被加到python运行环境下可以从该路径开始import脚本文件例如from tutorilaScripts import modMain |
| resource_packs | 存放客户端资源,可以包含多个资源包 |
| tutorialResource | 资源包 |
| worlds | 存放地图还包含world_behavior_packs.json和world_resource_packs.json |
| world_behavior_packs.json | 配置客户端需要下载的行为包 |
| world_resource_packs.json | 配置客户端需要下载的资源包 |
### 命名建议
建议behavior_packs、developer_mods、resource_packs目录下所有Mod都遵守"脚本开发入门"中"命名建议"Mod脚本根目录名建议采用`[团队名称][Mod名称][Scripts]`格式例如SDKTeamTestScripts。
### 服务器与客户端
游戏服Mod中客户端脚本和服务端脚本是分开两个目录存储的客户端脚本放到behavior_packs文件夹服务端脚本放到developer_mods文件夹两者是独立的不能相互import。客户端脚本只能使用”ModAPI“系列文档中客户端事件和客户端组件服务端脚本不仅能使用”ModAPI“系列文档中服务端端事件和服务端组件还能使用”Apollo网络服开发“文档中SDK。
游戏服Mod强烈建议客户端脚本只包含客户端逻辑服务端脚本只包含服务端逻辑一方面方便管理和开发代码另一方面还可以避免万一客户端脚本被破解而导致包含的服务端代码泄露。下面介绍如何让Mod只包含客户端或服务端代码
tutorialBehavior中脚本去掉服务端代码首先屏蔽ModMain.py中服务端代码注释掉TutorialServerInit和TutorialServerDestroy函数
```python
@Mod.Binding(name = "TutorialMod", version = "0.0.1")
class TutorialMod(object):
# 类的初始化函数
def __init__(self):
print "===== init tutorial mod ====="
# InitServer绑定的函数作为服务端脚本初始化的入口函数通常是用来注册服务端系统system和组件component
# @Mod.InitServer()
# def TutorialServerInit(self):
# print "===== init tutorial server ====="
# # 函数可以将System注册到服务端引擎中实例的创建和销毁交给引擎处理。第一个参数是MOD名称第二个是System名称第三个是自定义MOD System类的路径
# # 取名名称尽量个性化不能与其他人的MOD冲突可以使用英文、拼音、下划线这三种。
# serverApi.RegisterSystem("TutorialMod", "TutorialServerSystem", "tutorialScripts.tutorialServerSystem.TutorialServerSystem")
#
# # DestroyServer绑定的函数作为服务端脚本退出的时候执行的析构函数通常用来反注册一些内容,可为空
# @Mod.DestroyServer()
# def TutorialServerDestroy(self):
# print "===== destroy tutorial server ====="
# InitClient绑定的函数作为客户端脚本初始化的入口函数通常用来注册客户端系统system和组件component
@Mod.InitClient()
def TutorialClientInit(self):
print "===== init hugo fps client ====="
# 函数可以将System注册到客户端引擎中实例的创建和销毁交给引擎处理。第一个参数是MOD名称第二个是System名称第三个是自定义MOD System类的路径
# 取名名称尽量个性化不能与其他人的MOD冲突可以使用英文、拼音、下划线这三种。
clientApi.RegisterSystem("TutorialMod", "TutorialClientSystem", "tutorialScripts.tutorialClientSystem.TutorialClientSystem")
# DestroyClient绑定的函数作为客户端脚本退出的时候执行的析构函数通常用来反注册一些内容,可为空
@Mod.DestroyClient()
def TutorialClientDestroy(self):
print "===== destroy hugo fps client ====="
```
接着删除tutorialBehaviorPack目录下tutorialServerSystem.py文件。同样对于服务端只需屏蔽tutorialDev目录下ModMain.py文件中服务端代码也即注释掉TutorialClientInit和TutorialClientDestroy函数然后删除tutorialDev目录下tutorialClientSystem.py文件。
## 如何调试
网络游戏Mod代码目前只能通过在不同的地方打Log来调试代码。打Log可以使用 print 也可以使用 mod_log模块。客户端日志显示在”脚本测试日志“窗口中
![image-20210128150334059](./images/image-20210128150334059.png)
通常调试日志用print其他日志建议用mod_log模块例如
```python
from mod_log import logger
logger.info("print log: %s", "OK")
```
在MCStudio中找到网络游戏然后点击"更多",接着点击“查看服务端日志”,会弹出“服务器日志”窗口
![image-20210128150810194](./images/image-20210128150810194.png)
点击“大厅服”中“大厅服4000”可以查看服务器日志。网络游戏包含大厅服、游戏服、控制服、功能服、代理服目前服务器Mod是运行在大厅服大厅服日志包含了"===== init tutorial server ====="字符串它是执行服务端modMain.py文件中TutorialServerInit函数打印出来的
![image-20210128152712391](./images/image-20210128152712391.png)
最后我们验证游戏服Mod功能使用客户端进入游戏服后聊天框中输入“钻石剑”玩家背包中多了一把钻石剑
![image-20210128153503054](./images/image-20210128153503054.png)
## 使用MCStudio将Mod转化成网络游戏Mod
MCStudio可以直接将Mod转换成网络游戏Mod我们以“入门脚本模板”为示例介绍转换方法
MCStudio中点击新建→基岩版组件→入门脚本模板点击新建会自动创建一个“入门脚本模板“的AddOn。
![image-20210223144721613](./images/image-20210223144721613.png)
MCStudio中点击基岩版组件找到新建的入门脚本模板点击更多→转换为服务端Mod
![image-20210223144701813](./images/image-20210223144701813.png)
输入Mod名字为tutorialApolloModV2点击转换我们就得到一个网络游戏Mod了
![image-20210223144935188](./images/image-20210223144935188.png)
打开网络游戏Mod可以看看转换后Mod的目录这是MCStudio替我们执行了上面“Mod转化成网络游戏Mod”过程但是转换后Mod的客户端和服务端逻辑还没有分离需要按照“服务器与客户端”进行调整。
![image-20210223145148829](./images/image-20210223145148829.png)
## 开始行动吧
首先阅读“ModSDK模组开发”然后从modMain.py入手阅读tutorialApolloMod的代码与注释。
完全理解后在服务端事件以及服务端组件中找几个自己感兴趣的尝试添加到网络游戏Mod里看能不能生效吧
掌握事件与组件的用法后可以阅读Apollo中“SDK”文档学习更多Apollo的用法然后阅读“网络服开发进阶”全面学习网络游戏Mod开发技巧。阅读完成后可添加一些Apollo SDK尝试运行并查看是否生效。
掌握Apollo “SDK”后可以阅读“官方插件介绍”然后开发自己的小游戏了。
遇到自身没法解决的问题时,及时和官方沟通反馈。

View File

@@ -0,0 +1,173 @@
---
front:
hard: 进阶
time: 20分钟
---
# Mod和网络游戏Mod相互转换
本教材介绍如何将Mod转换成网络游戏Mod然后再将网络游戏Mod转换成Mod。与“Mod到网络游戏Mod入门”教材不同本教材介绍的方法可以实现Mod和网络游戏Mod的相互转换而“Mod到网络游戏Mod入门”只能实现Mod到网络游戏Mod的单向转换。本教材要求开发者已经申请到了开发机按照“网络游戏入驻”流程申请且会使用部署工具参考“使用部署工具”已经阅读“Mod到网络游戏Mod入门”
网络游戏Mod绝大部分时间花在Mod开发上服主可以使用Mod API开发调试实现大部分客户端和服务端逻辑还可以本地查看效果大大提升开发效率。本地开发完成后再转换成网络游戏Mod使用Apollo SDK实现网络游戏相关的功能。服主也可以把网络游戏Mod转换成Mod使用本机开发调试。相互转换的条件是不允许使用Apollo SDK中的API。下面我们以基岩版“入门脚本模板”为例说明他们之间的转换。
## Mod转化成网络游戏Mod
这里以入门脚本模板为例介绍从入门脚本模板Mod转化成入门脚本网络游戏Mod的步骤。
1、入门脚本模板中点击“更多-->转换为服务端Mod”Mod名字为tutorialApolloMod
![](./images/image-zhuanhuan9.png)
在服务端Mod中可以找到tutorialApolloMod
![](./images/image-zhuanhuan8.png)
2、打开tutorialApolloMod所在目录修改tutorialApolloMod脚本根目录名将tutorialScripts改为tutorialScriptsDev
![](./images/image-zhuanhuan7.png)
由于改了根目录名所以需要将tutorialApolloMod/tutorialScriptsDev目录中所有使用“tutorialScripts”的python包都改为“tutorialScriptsDev”。在tutorialScriptsDev目录下搜索tutorialScripts发现只需改modMain.py文件替换之后核心代码如下
```python
class TutorialMod(object):
...
@Mod.InitServer()
def TutorialServerInit(self):
#serverApi.RegisterSystem("TutorialMod", "TutorialServerSystem", "tutorialScripts.tutorialServerSystem.TutorialServerSystem") #包含了tutorialScripts的python包需要改名为tutorialScriptsDev
serverApi.RegisterSystem("TutorialMod", "TutorialServerSystem", "tutorialScriptsDev.tutorialServerSystem.TutorialServerSystem")
@Mod.InitClient()
def TutorialClientInit(self):
#clientApi.RegisterSystem("TutorialMod", "TutorialClientSystem", "tutorialScripts.tutorialClientSystem.TutorialClientSystem")#包含了tutorialScripts的python包需要改名为tutorialScriptsDev
clientApi.RegisterSystem("TutorialMod", "TutorialClientSystem", "tutorialScriptsDev.tutorialClientSystem.TutorialClientSystem")
...
```
3、ModMain.py中注释不相关的代码。客户端ModMain.py文件只包含客户端的入口和退出函数需要屏蔽TutorialServerInit和TutorialServerDestroy函数
```python
@Mod.Binding(name = "TutorialMod", version = "0.0.1")
class TutorialMod(object):
# 类的初始化函数
def __init__(self):
print "===== init tutorial mod ====="
# # InitServer绑定的函数作为服务端脚本初始化的入口函数通常是用来注册服务端系统system和组件component
# @Mod.InitServer()
# def TutorialServerInit(self):
# print "===== init tutorial server ====="
# # 函数可以将System注册到服务端引擎中实例的创建和销毁交给引擎处理。第一个参数是MOD名称第二个是System名称第三个是自定义MOD System类的路径
# # 取名名称尽量个性化不能与其他人的MOD冲突可以使用英文、拼音、下划线这三种。
# serverApi.RegisterSystem("TutorialMod", "TutorialServerSystem", "tutorialScripts.tutorialServerSystem.TutorialServerSystem")
# # DestroyServer绑定的函数作为服务端脚本退出的时候执行的析构函数通常用来反注册一些内容,可为空
# @Mod.DestroyServer()
# def TutorialServerDestroy(self):
# print "===== destroy tutorial server ====="
# InitClient绑定的函数作为客户端脚本初始化的入口函数通常用来注册客户端系统system和组件component
@Mod.InitClient()
def TutorialClientInit(self):
print "===== init hugo fps client ====="
# 函数可以将System注册到客户端引擎中实例的创建和销毁交给引擎处理。第一个参数是MOD名称第二个是System名称第三个是自定义MOD System类的路径
# 取名名称尽量个性化不能与其他人的MOD冲突可以使用英文、拼音、下划线这三种。
clientApi.RegisterSystem("TutorialMod", "TutorialClientSystem", "tutorialScripts.tutorialClientSystem.TutorialClientSystem")
# DestroyClient绑定的函数作为客户端脚本退出的时候执行的析构函数通常用来反注册一些内容,可为空
@Mod.DestroyClient()
def TutorialClientDestroy(self):
print "===== destroy hugo fps client ====="
```
服务端ModMain.py只包含服务端的入口和退出函数屏蔽TutorialClientInit和TutorialClientDestroy函数。
4、转换完成部署后点击“大厅服”中“大厅服4000”可以查看服务器日志日志包含“===== init tutorial server =====”它是执行服务端modMain.py文件中TutorialServerInit函数打印出来的
![](./images/image-zhuanhuan1.png)
## 网络游戏Mod转化成Mod
这里以入门脚本模板为例介绍从入门脚本网络游戏Mod转化成入门脚本Mod的步骤。
为了查看转换效果分别在客户端Mod和服务端Mod中新增一条日志。在服务端Mod的tutorialServerSystem.py文件中新增一条日志
```python
class TutorialServerSystem(ServerSystem):
# ServerSystem的初始化函数
def __init__(self, namespace, systemName):
# 首先调用父类的初始化函数
super(TutorialServerSystem, self).__init__(namespace, systemName)
print "===== TutorialServerSystem init ====="
print "===== server test init ====="
```
在客户端Mod的tutorialClientSystem.py文件中新增一条日志
```python
class TutorialClientSystem(ClientSystem):
# 客户端System的初始化函数
def __init__(self, namespace, systemName):
# 首先初始化TutorialClientSystem的基类ClientSystem
super(TutorialClientSystem, self).__init__(namespace, systemName)
print "==== TutorialClientSystem Init ===="
print "===== client test init ====="
```
**转换前需要确保没有使用任何Apollo SDK中API**,下面介绍转换过程:
1、创建一个空白的AddOn针对没有使用地图的网络游戏删除behavior、resource相关目录删除world_behavior_packs.json和world_resource_packs.json
2、将网络服behavior_packs、resource_packs、worlds/level 目录下所有内容拷贝到入门Mod所在目录下
![](./images/image-zhuanhuan4.png)
3、将developer_mods/tutorialApolloMod 下内容拷贝到入门Mod的tutorialApolloModBehavior目录下
4、转换完成然后开发测试发现打印了“===== server test init =====”和“===== client test init =====”日志
![](./images/image-zhuanhuan3.png)
5、tutorialApolloModBehavior目录下包含两个脚本目录tutorialScripts和tutorialScriptsDev。要求服主在tutorialScripts中开发客户端逻辑在tutorialScriptsDev中开发服务端逻辑。再次将Mod转换成网络游戏Mod时只需将tutorialScriptsDev到拷贝网络服developer/tutorialApolloMod目录将tutorialApolloModBehavior拷贝到网络服behavior_packs目录将tutorialApolloModResource拷贝到网络服resource_packs目录将world_behavior_packs.json、world_resource_packs.json拷贝到网络服worlds/level 目录
## 网络游戏Mod和Mod相互转换
上面是处理不带地图的网络游戏下面介绍如何将带地图的网络服Mod转出Mod以入门脚本网络游戏Mod新增了地图为例做说明
1、新建一个空白的**地图Mod**针对有使用地图的网络游戏删除Mod所在目录中behavior_packs、db、resource_packs目录
2、将网络服Mod中behavior_packs、resource_packs目录拷贝到Mod所在目录将level目录下全部内容拷贝到Mod所在目录将developer_mods中脚本根目录developer_mods/tutorialApolloMod/tutorialScriptsDev拷贝到任意一个behavior_packs的Mod里面也即将网络服developer_mods/tutorialApolloMod/tutorialScriptsDev拷贝到Mod的behavior_packs/tutorialApolloModBehavior 目录中
![](./images/image-zhuanhuan2.png)
执行上面步骤后就完成了网络游戏Mod到Mod转换完成开发调试后可以进行逆向转换也就是将上面Mod转换成网络游戏Mod。具体过程是
1、将behavior_packs、resource_packs拷贝到网络服tutorialApolloMod目录下将behavior_packs/tutorialApolloModBehavior/tutorialScriptsDev拷贝到tutorialApolloMod/developer_mods目录
2、将db、level.dat、level.dat_old、levelname.txt、world_behavior_packs.json、world_resource_packs.json拷贝到worlds/level目录下