feat:上传mcguide-开发指南部份

This commit is contained in:
Othniel su
2024-12-23 10:57:59 +08:00
parent 7292166c88
commit 0dc59fa4f0
3297 changed files with 63375 additions and 0 deletions

View File

@@ -0,0 +1,304 @@
---
front: https://nie.res.netease.com/r/pic/20220408/080f488a-4975-4f9e-a9c6-d1d404bed919.png
hard: 入门
time: 30分钟
selection: true
---
# 脚本开发入门
## 什么是Python脚本开发
原生的AddOn的方式可以改变很多原版游戏内容以及添加自定义的游戏内容但一般无法实现一些较复杂的逻辑比如右键自定义方块时会给予物品。这就需要使用脚本来实现了。
在我的世界中国版中我们使用python来编写mod脚本。
我们封装了很多的游戏事件与组件,游戏事件是指游戏内触发了某个操作或达到某一种条件(例如玩家右键了自定义方块),可以通知到我们的代码,进而实现我们的逻辑。组件是我们封装好的游戏引擎接口,可以用来设置或获取某些数据(例如操作玩家背包),或者执行一些特殊的功能。
脚本开发就是一个监听事件与调用组件的过程,配合自己的逻辑来实现很酷的玩法。
## 第一个脚本Mod
在启动器→新建基岩版组件窗口→推荐分页→入门脚本模板,点击新建,会自动创建一个“入门脚本模板“的附加包。
<img src="./picture/python_intro/1.png" alt="image-20200426111316794" style="zoom:67%;" />
然后我们直接选择这个AddOn进入开发测试。进入游戏后我们在聊天栏输入“钻石剑”就会发现在背包里多了一把钻石剑。这个是使用原版AddOn无法实现的效果。
下面我们通过尝试修改入门模板来了解如何进行Python脚本开发。
![image-20200426112017092](./picture/python_intro/2.png)
## 开发环境搭建
### python安装
**我们的python脚本开发使用的python版本是python 2而不是python 3**
我们进入[python官网下载页](https://www.python.org/downloads/)拖到下面的“Looking for a specific release”然后点进最新的python2的版本。
<img src="./picture/python_intro/3.png" alt="image-20200426113913436" style="zoom:67%;" />
<img src="./picture/python_intro/4.png" alt="image-20200426114129864" style="zoom:50%;" />
安装时需要选择将python添加到环境变量中其余按照提示点下一步即可。
<img src="./picture/python_intro/16.png" alt="image-20200426114129864"/>
### IDE安装
集成开发环境(*IDE*可以很好帮助我们编写代码对于python来说pycharm与vscode都是很不错的IDE这里我们以pycharm为例
进入pycharm的[官网下载页](https://www.jetbrains.com/pycharm/download)选择Community版本下载然后按照提示点下一步安装即可。
<img src="./picture/python_intro/5.png" alt="image-20200426114531121" style="zoom:50%;" />
### 安装Mod SDK补全库
#### 使用mcstudio安装
打开studio编辑器点击工具
若只有稳定版本存在时,开发者可点击稳定版补全库下载。
若beta版本与稳定版本共存的时候开发者可根据需要选择所需要的版本补全库。
点击检查补全库更新,可把最新版本的补全库更新到菜单列表。
![image-20200426115234286](./picture/python_intro/17.png)
#### 手动安装补全库
对于高端开发者可以使用pip来安装补全库。
* 安装
在命令行中输入以下指令即可安装最新版的补全库
```
python -m pip install mc-netease-sdk
```
* 升级
补全库有新版本时可以使用以下指令升级到最新版本如果存在新版本的beta补全库时这种方法会将本地的补全库更新到最新的beta版
```
python -m pip install --upgrade mc-netease-sdk
```
* 安装到指定的python
当系统内有多个python时可以指定python的路径来安装到对应的python
```
C:\xxx\python.exe -m pip install mc-netease-sdk
```
* 安装特定版本的补全库
在[pypi](https://pypi.org/project/mc-netease-sdk)上查询可选的版本,然后使用:
```
python -m pip install mc-netease-sdk==要安装的版本号
```
## Python入门
python是一门很容易入门的编程语言没有接触过python的开发者可以先浏览[这个网站](https://www.liaoxuefeng.com/wiki/1016959663602400)的下面这些页面跟着上面的示例代码来了解python
* 第一个Python程序
* 使用文本编辑器
* Python基础
* 数据类型和变量
* 条件判断和循环
* 使用dict
* 函数
* 调用函数
* 定义函数
* 函数的参数
* 模块
* 使用模块
* 面向对象编程
* 类和示例
## 为自定义方块mod添加脚本
1. 打开“入门脚本模板”的目录打开“tutorialBehaviorPack_xxx”文件夹把里面的“tutorialScripts”复制到我们在“制作第一个Mod”中创建的自定义方块AddOn的行为包中。
<img src="./picture/python_intro/7.png" alt="image-20200426143417561" style="zoom:67%;" />
2. 用IDE打开自定义方块AddOn的行为包并且配置python环境。
以pycharm为例点open然后把行为包的路径拷贝进来打开。
<img src="./picture/python_intro/8.png" alt="image-20200426150351934" style="zoom:67%;" />
然后选择File→Settings→Project: behavior_pack_xxx→Python Interpreter点设置按钮然后Add。然后选System Interpreter然后选择我们刚才安装的python路径。然后我们就可以使用pycharm的自动补全功能了
<img src="./picture/python_intro/9.png" alt="image-20200426151222221" style="zoom:50%;" />
<img src="./picture/python_intro/10.png" alt="image-20200426151341683" style="zoom:50%;" />
3. 实现右键自定义方块时获得钻石剑
打开tutorialScripts/tutorialServerSystem.py我们看到监控聊天信息并生成物品的代码。
我们通过监听ServerChatEvent然后在响应函数里用item组件向玩家背包添加物品。
![image-20200426161036254](./picture/python_intro/11.png)
我们参考这些代码来实现右键自定义方块的逻辑。
首先我们在ListenEvent函数里监听ServerBlockUseEvent事件然后添加一个OnServerBlockUseEvent函数用来处理这个事件。根据文档我们可以知道这个事件会告诉我们执行这个操作的玩家以及右键的方块的信息。根据这些信息我们使用与OnServerChat函数一样的方法给玩家的背包添加一个钻石剑。
```python
def ListenEvent(self):
# 在自定义的ServerSystem中监听引擎的事件ServerChatEvent回调函数为OnServerChat
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerChatEvent", self, self.OnServerChat)
# 监听引擎的事件ServerBlockUseEvent回调函数为ServerBlockUseEvent
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerBlockUseEvent",
self, self.OnServerBlockUseEvent)
...
# 监听ServerBlockUseEvent的回调函数
def OnServerBlockUseEvent(self, args):
# 这里的sdkteam_test:block1替换成你自己的自定义方块的命名空间与方块名
if args["blockName"] == "sdkteam_test:block1":
# 调用给予物品的接口与OnServerChat中相似
comp = serverApi.CreateComponent(serverApi.GetLevelId(), "Minecraft", "item")
# 这里填钻石剑的物品名
comp.SpawnItemToPlayerInv({"itemName":"minecraft:diamond_sword", "count":1, 'auxValue': 0}, args["playerId"])
```
![image-20200426175557208](./picture/python_intro/15.png)
4. 再次进入测试存档,右键我们的自定义方块,发现背包添加了钻石剑。
如果一直点着右键会发现背包一下子就被钻石剑填满了。这是因为ServerBlockUseEvent事件每一帧tick都会触发开发者在阅读文档时也应留意。
![image-20200426164102870](./picture/python_intro/12.png)
## 脚本结构
我们以tutorialScripts为例来讲解python脚本的目录结构。
``` json
| behavior_packs_xxx
| entities
| tutorialScripts
| __init__.py
| modMain.py
| tutorialClientSystem.py
| tutorialServerSystem.py
| ...
| manifest.json
```
| 文件/文件夹 | 解释 |
| ----------------------- | ------------------------------------------------------------ |
| tutorialScripts | python脚本的根目录该目录的脚本会被加到python运行环境下可以从该路径开始import脚本文件例如from tutorilaScripts import modMain |
| \_\_init\_\_.py | 是python module的标识表示这是一个可以import的module同时也可以做一些初始化的操作,内容可为空,但是文件必须有。 |
| modMain.py | 必须有该文件用来初始化我们的Mod |
| tutorialClientSystem.py | 执行客户端逻辑的system |
| tutorialServerSystem.py | 执行服务器逻辑的system |
### 命名建议
为了与其他mod的脚本区分以免发生冲突脚本的目录应该有足够的区分度。
建议采用`[团队名称][Mod名称][Scripts]`格式例如SDKTeamTestScripts。这个文件夹更改命名后代码里相应的地方也需要修改。
### modMain.py是什么
modMain是Python逻辑的入口文件需要包含mod的初始化与退出时的处理函数。这些初始化函数中InitClient和InitServer分别初始化客户端和服务端通常用于系统与组件的注册也可以做一些自定义的初始化操作。DestroyServer和DestroyClient用来做一些退出游戏时的处理例如保存数据恢复一些设置或销毁一些内容。
``` python
# Mod属于SDK的内部类用于绑定
from mod.common.mod import Mod
# 将引擎的方法绑定到我们自己的类HugoMod上用于识别
@Mod.Binding(name = "HugoMod", version = "0.0.1")
class HugoMod(object):
def __init__(self):
pass
# 服务端脚本初始化的入口函数
@Mod.InitServer()
def testServerInit(self):
pass
# 服务端脚本在退出时执行的析构函数
@Mod.DestroyServer()
def testServerDestroy(self):
pass
# 客户端脚本初始化的入口函数
@Mod.InitClient()
def testClientInit(self):
pass
# 客户端脚本在退出时执行的析构函数
@Mod.DestroyClient():
def testClientDestroy(self):
pass
```
| 代码 | 解释 |
| ----------------------------------------------- | ------------------------------------------------------------ |
| from mod.common.mod import Mod | Mod是一个注册类需要用其来绑定类和函数 |
| @Mod.Binding(name = "HugoMod", version = "1.0") | HugoMod是我们的Mod类name表示Mod的名称version表示Mod 的版本 |
| @Mod.InitServer() | 作用是标识该函数是我们的Server端初始化的函数会在游戏Server端开始的时候被调用 |
| @Mod.DestroyServer() | 作用是用来标识我们的Server端关闭的时候执行的一些销毁内容的函数 |
| @Mod.InitClient() | 作用是用来标识我们的Client端开始的时候执行初始化的函数会在游戏Client端开始的时候被调用 |
| @Mod.DestroyClient() | @Mod.DestroyClient()的作用是用来标识我们的CLient端关闭的时候执行一些销毁操作会在游戏Client端关闭的时候被调用 |
### 服务器与客户端
还记得我们在[Mod是如何工作的](../1-Mod开发简介/3-Mod是如何工作的.md)中提到的Client-Server架构吗脚本开发也分为服务端脚本与客户端脚本这就是为什么我们需要InitServerInitClient以及ServerSystem和ClientSystem。
在”ModAPI“系列文档中也可以看到事件分为服务端事件与客户端事件组件分为服务端组件与客户端组件。服务端与客户端的脚本需要互相独立两部分的代码不要互相import使用对方的事件与组件也不会生效。一般情况下我们需要把游戏逻辑相关的代码写在服务端例如给予物品把表现相关的代码写在客户端例如UI与特效。而服务器与客户端之间的通信会用到“自定义事件”在后面阅读AwesomeMod时学习。
## 如何调试
Mod代码目前不支持断点调试因此只能通过在不同的地方打Log来调试代码。打Log可以使用 print 也可以使用 logging模块后面阅读AwesomeMod时会看到。Log会显示在”脚本测试日志“窗口中脚本的Log最好加上特殊的前缀方便查找。
<img src="./picture/python_intro/13.png" alt="image-20200426173147577" style="zoom:67%;" />
推荐使用mod_log模块打印日志
```python
from mod_log import logger
logger.info("print log: %s", "OK")
```
目前Mod代码支持热更新调试在运行游戏进行开发测试时增加删除修改相关本地Python文件后回到Studio或者编辑器界面Studio会自动热更新修改的内容并在”脚本测试日志“窗口中提示“正在重载相关的Python模块”。
如下图所示原本点击开始游戏会打印出日志“test 1”。修改打印内容为“test 2”后点击”脚本测试日志“窗口时会输出"正在重载script_StartLogic.StartLogicUI"然后再次点击开始游戏打印的内容变成了“test 2”。
<img src="./picture/python_intro/16.gif" alt="image-20200426173147577" style="zoom:100%;" />
自动热更对**函数内实现**具有较好的支持,但涉及到**全局变量,新增类/文件**等可能无法生效。
此时可以通过**保存退出到菜单界面**后,再**重新进入存档**以完整加载修改后的MOD。
## 开始行动吧
首先阅读[系统简介](./4-系统简介.html)[事件简介](../2-Python脚本开发/9-事件简介.md)[组件简介](./8-组件简介.html)然后从modMain.py入手阅读[TutorialMod](../60-Demo示例.md#TutorialMod)的代码与注释。
掌握了事件与组件的用法后,可以阅读我们提供的射击玩法示例[AwesomeMod](../60-Demo示例.md#AwesomeMod)来学习更多的MOD开发技巧从modMain.py开始入手哦
熟悉了modsdk的用法后可以继续阅读[这个网站](https://www.liaoxuefeng.com/wiki/1016959663602400)的“高级特性”“面向对象编程”“常用内建模块”有助于使用python编写出更复杂的玩法逻辑。
遇到自身没法解决的问题时,及时通过频道或开发者频道的反馈功能和官方沟通。

View File

@@ -0,0 +1,139 @@
# 2.12版本物品id变更
## 简介
2.12版本与2.11版本相比有部分物品的名称发生了变更取消了附加值例如橙色羊毛从minecraft:wool 1变为minecraft:orange_wool云杉原木从minecraft:log 1变为minecraft:spruce_log。
## 处理方法
在ModSDK的接口与事件中我们针对上述情况做了以下处理
1. 对于返回物品信息字典的接口与事件:
newItemName及newAuxValue返回新版名称与附加值。
原字段itemName及auxValue返回旧版名称与附加值。
2. 对于接受物品信息字典的接口与事件:
当字典存在newItemName及newAuxValue时使用这两个字段。
不存在时使用旧字段itemName及auxValue。
## 注意事项
* 通过附加值获取获取方块状态接口没有做兼容例如GetBlockAuxValueFromStates、GetBlockStatesFromAuxValue、GetBlockStates、SetBlockStates如果您的组件对此有依赖则需要对这次的改动自行做兼容处理。
* **开发完成或正在开发的组件建议统一采用newItemName及newAuxValue字段也不要新旧字段混用。**
* 某些写法可能会失效,例如
```python
# 获取itemDict然后在他基础上修改itemName或auxValue后再用来生成
itemdict = GetPlayerItem()
itemdict['itemName'] = 'xxx'
itemdict['auxValue'] = itemdict['auxValue']+1
SpawnItemToPlayerInv(itemdict)
```
因为GetPlayerItem返回的itemDict含有新字段再传入SpawnItemToPlayerInv时会读取新字段生成物品因此对原字段的修改无效。
## 物品名称变更表
以下为2.12版本变更了名称的物品列表。表格内的名称省略了minecraft命名空间。
| 中文名称 | 旧命名 | 旧附加值 | 新命名 |
| :------------- | ----------- | -------- | ---------------------- |
| 白色羊毛 | wool | 0 | white_wool |
| 橙色羊毛 | wool | 1 | orange_wool |
| 品红色羊毛 | wool | 2 | magenta_wool |
| 淡蓝色羊毛 | wool | 3 | light_blue_wool |
| 黄色羊毛 | wool | 4 | yellow_wool |
| 黄绿色羊毛 | wool | 5 | lime_wool |
| 粉红色羊毛 | wool | 6 | pink_wool |
| 灰色羊毛 | wool | 7 | gray_wool |
| 淡灰色羊毛 | wool | 8 | light_gray_wool |
| 青色羊毛 | wool | 9 | cyan_wool |
| 紫色羊毛 | wool | 10 | purple_wool |
| 蓝色羊毛 | wool | 11 | blue_wool |
| 棕色羊毛 | wool | 12 | brown_wool |
| 绿色羊毛 | wool | 13 | green_wool |
| 红色羊毛 | wool | 14 | red_wool |
| 黑色羊毛 | wool | 15 | black_wool |
| 橡木原木 | log | 0 | oak_log |
| 云杉原木 | log | 1 | spruce_log |
| 白桦原木 | log | 2 | birch_log |
| 丛林原木 | log | 3 | jungle_log |
| 金合欢原木 | log2 | 0 | acacia_log |
| 深色橡木原木 | log2 | 1 | dark_oak_log |
| 橡木栅栏 | fence | 0 | oak_fence |
| 云杉木栅栏 | fence | 1 | spruce_fence |
| 白桦木栅栏 | fence | 2 | birch_fence |
| 丛林木栅栏 | fence | 3 | jungle_fence |
| 金合欢木栅栏 | fence | 4 | acacia_fence |
| 深色橡木栅栏 | fence | 5 | dark_oak_fence |
| 管珊瑚 | coral | 0 | tube_coral |
| 脑纹珊瑚 | coral | 1 | brain_coral |
| 气泡珊瑚 | coral | 2 | bubble_coral |
| 火珊瑚 | coral | 3 | fire_coral |
| 鹿角珊瑚 | coral | 4 | horn_coral |
| 失活的管珊瑚 | coral | 8 | dead_tube_coral |
| 失活的脑纹珊瑚 | coral | 9 | dead_brain_coral |
| 失活的气泡珊瑚 | coral | 10 | dead_bubble_coral |
| 失活的火珊瑚 | coral | 11 | dead_fire_coral |
| 失活的鹿角珊瑚 | coral | 12 | dead_horn_coral |
| 白色地毯 | carpet | 0 | white_carpet |
| 橙色地毯 | carpet | 1 | orange_carpet |
| 品红色地毯 | carpet | 2 | magenta_carpet |
| 淡蓝色地毯 | carpet | 3 | light_blue_carpet |
| 黄色地毯 | carpet | 4 | yellow_carpet |
| 黄绿色地毯 | carpet | 5 | lime_carpet |
| 粉红色地毯 | carpet | 6 | pink_carpet |
| 灰色地毯 | carpet | 7 | gray_carpet |
| 淡灰色地毯 | carpet | 8 | light_gray_carpet |
| 青色地毯 | carpet | 9 | cyan_carpet |
| 紫色地毯 | carpet | 10 | purple_carpet |
| 蓝色地毯 | carpet | 11 | blue_carpet |
| 棕色地毯 | carpet | 12 | brown_carpet |
| 绿色地毯 | carpet | 13 | green_carpet |
| 红色地毯 | carpet | 14 | red_carpet |
| 黑色地毯 | carpet | 15 | black_carpet |
| 白色潜影盒 | shulker_box | 0 | white_shulker_box |
| 橙色潜影盒 | shulker_box | 1 | orange_shulker_box |
| 品红色潜影盒 | shulker_box | 2 | magenta_shulker_box |
| 淡蓝色潜影盒 | shulker_box | 3 | light_blue_shulker_box |
| 黄色潜影盒 | shulker_box | 4 | yellow_shulker_box |
| 黄绿色潜影盒 | shulker_box | 5 | lime_shulker_box |
| 粉红色潜影盒 | shulker_box | 6 | pink_shulker_box |
| 灰色潜影盒 | shulker_box | 7 | gray_shulker_box |
| 淡灰色潜影盒 | shulker_box | 8 | light_gray_shulker_box |
| 青色潜影盒 | shulker_box | 9 | cyan_shulker_box |
| 紫色潜影盒 | shulker_box | 10 | purple_shulker_box |
| 蓝色潜影盒 | shulker_box | 11 | blue_shulker_box |
| 棕色潜影盒 | shulker_box | 12 | brown_shulker_box |
| 绿色潜影盒 | shulker_box | 13 | green_shulker_box |
| 红色潜影盒 | shulker_box | 14 | red_shulker_box |
| 黑色潜影盒 | shulker_box | 15 | black_shulker_box |
| 白色混凝土 | concrete | 0 | white_concrete |
| 橙色混凝土 | concrete | 1 | orange_concrete |
| 品红色混凝土 | concrete | 2 | magenta_concrete |
| 淡蓝色混凝土 | concrete | 3 | light_blue_concrete |
| 黄色混凝土 | concrete | 4 | yellow_concrete |
| 黄绿色混凝土 | concrete | 5 | lime_concrete |
| 粉红色混凝土 | concrete | 6 | pink_concrete |
| 灰色混凝土 | concrete | 7 | gray_concrete |
| 淡灰色混凝土 | concrete | 8 | light_gray_concrete |
| 青色混凝土 | concrete | 9 | cyan_concrete |
| 紫色混凝土 | concrete | 10 | purple_concrete |
| 蓝色混凝土 | concrete | 11 | blue_concrete |
| 棕色混凝土 | concrete | 12 | brown_concrete |
| 绿色混凝土 | concrete | 13 | green_concrete |
| 红色混凝土 | concrete | 14 | red_concrete |
| 黑色混凝土 | concrete | 15 | black_concrete |

View File

@@ -0,0 +1,19 @@
---
front:
hard: 入门
time: 分钟
---
# <span id="系统简介"></span>系统简介
系统System是我们的核心类用于监听事件使用组件更新等。
获取自定义的System需要继承引擎的系统基类 ClientSystem/ServerSystem.
```python
import client.extraClientApi as clientApi
ClientSystem = clientApi.GetClientSystemCls()
import server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
```

View File

@@ -0,0 +1,12 @@
---
front:
hard: 入门
time: 分钟
---
# <span id="组件简介"></span>组件简介
- 组件是为了完成某个或某些特定逻辑功能的数据集合组件只会保存数据并不会执行相应的逻辑只有组件在System中更新的时候System从判断组件是否需要更新从组件中拿到需要更新的数据来执行相应的逻辑功能。
- 组件分为引擎组件和自定义组件。引擎组件的参数类型和功能都是确定好的玩家可以创建Create或获取Get组件来完成逻辑功能。自定义组件需要自定义组件的数据结构自定义组件的更新逻辑。

View File

@@ -0,0 +1,60 @@
---
front:
hard: 入门
time: 分钟
---
# <span id="事件简介"></span>事件简介
事件依赖于系统事件需要系统才能监听触发因此在使用事件之前需要先拥有自己的系统system。事件分为 监听事件、反监听、发布事件和响应事件。
* 监听事件
监听事件的含义是将回调函数注册到事件上当事件发生时主动调用该回调函数。监听函数ListenForEvent
* 反监听事件
不再需要监听的事件可以使用UnListenForEvent函数取消监听
* 发布事件
发布事件是指在事件发生时发布这个事件通知所有监听了这个事件的回调函数。引擎定义的事件会在引擎事件发生时自动发布自定义事件的发布需要在需要的地方进行发布需要先CreateEventData创建事件数据发布函数有BroadcastEvent / NotifyToClient / BroadcastToAllClient / NotifyToServer.
* 响应事件
上述的发布事件很多都是广播但是不是每条消息都需要每个system都处理因此响应函数只会响应那些监听了这些事件且消息源有发布这些事件的时候才会响应。
响应函数会响应在监听事件时ListenForEvent的参数中的回调函数。**回调函数必须传入一个参数**类型一般为dict不同事件的参数在下面具体事件中进行了说明其中部分参数是可设置参数可以通过修改值来改变事件的结果。
* 示例
```python
class MyClientSystem(ClientSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
# 注册监听
self.ListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), 'AddEntityEvent', self, self.OnAddEntity)
self.ListenForEvent(clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName(), 'ClientJumpButtonPressDownEvent', self, self.OnClientJumpButtonPressDown)
# 监听回调函数
def OnAddEntity(self, data):
entityId = data["id"]
logger.info("AddEntityEvent callback... data: %s" % data)
def OnClientJumpButtonPressDown(self, data):
# continueJump是可设置参数可设置是否执行跳跃逻辑
data["continueJump"] = False
```
**请勿对引擎事件的回调参数添加自定义的key**,如有需要利用回调参数的字典做其他逻辑,请进行拷贝,例如:
```python
# 某回调函数
def OnAddEntity(self, data):
myData = {
"id": data["id"],
"myKey": "myValue"
}
do_something(myData)
```

View File

@@ -0,0 +1,219 @@
---
front: https://nie.res.netease.com/r/pic/20210727/82dd4b1e-04e1-4a90-a4c5-1a4d5cec462a.png
hard: 入门
time: 10分钟
---
# 1.23版本物品id变更
## 简介
1.23版本与1.22版本相比有部分物品的名称发生了变更例如生鱼从minecraft:fish变为minecraft:cod牛奶桶从minecraft:bucket附加值为1改为minecraft:milk_bucket附加值为0。
## 处理方法
在ModSDK的接口与事件中我们针对上述情况做了以下处理
1. 对于接受物品名称与附加值的接口,同时兼容旧版名称与新版名称
如SetUiItem接口
2. 在物品信息字典中添加newItemName及newAuxValue字段。
* 对于返回物品信息字典的接口与事件:
新字段newItemName及newAuxValue返回新版名称与附加值。
原字段itemName及auxValue返回旧版名称与附加值。
例如GetPlayerItem接口OnCarriedNewItemChangedServerEvent事件
* 对于接受物品信息字典的接口与事件:
当字典存在newItemName及newAuxValue时使用这两个新字段。
不存在时使用旧字段itemName及auxValue。
例如SpawnItemToPlayerCarried接口EntityDieLoottableServerEvent事件
## 注意事项
* 获取配方的接口返回值没有做兼容例如GetRecipeResultGetRecipesByResultGetRecipesByInput将返回新版名称与附加值如果您的组件对此有依赖则需要对这次的改动自行做兼容处理。
* 新开发或正在开发的组件建议统一采用新的newItemName及newAuxValue字段也不要新旧字段混用。
* 某些写法可能会失效,例如
```python
# 获取itemDict然后在他基础上修改itemName或auxValue后再用来生成
itemdict = GetPlayerItem()
itemdict['itemName'] = 'xxx'
itemdict['auxValue'] = itemdict['auxValue']+1
SpawnItemToPlayerInv(itemdict)
```
因为GetPlayerItem返回的itemDict含有新字段再传入SpawnItemToPlayerInv时会读取新字段生成物品因此对原字段的修改无效。
## 物品名称变更表
以下为1.23版本变更了名称的物品列表。表格内的名称省略了minecraft命名空间。
| 旧名称 | 旧附加值 | 新名称 |
| ------------------- | ---------- | ------------------------------- |
| carrotonastick | | carrot_on_a_stick |
| fish | | cod |
| cooked_fish | | cooked_cod |
| clownfish | | tropical_fish |
| muttoncooked | | cooked_mutton |
| appleenchanted | | enchanted_golden_apple |
| fireball | | fire_charge |
| fireworks | | firework_rocket |
| fireworkscharge | | firework_star |
| speckled_melon | | glistering_melon_slice |
| record_11 | | music_disc_11 |
| record_13 | | music_disc_13 |
| record_blocks | | music_disc_blocks |
| record_cat | | music_disc_cat |
| record_chirp | | music_disc_chirp |
| record_far | | music_disc_far |
| record_mall | | music_disc_mall |
| record_mellohi | | music_disc_mellohi |
| record_pigstep | | music_disc_pigstep |
| record_stal | | music_disc_stal |
| record_strad | | music_disc_strad |
| record_wait | | music_disc_wait |
| record_ward | | music_disc_ward |
| muttonraw | | mutton |
| netherstar | | nether_star |
| chorus_fruit_popped | | popped_chorus_fruit |
| melon | | melon_slice |
| reeds | | sugar_cane |
| horsearmorleather | | leather_horse_armor |
| horsearmoriron | | iron_horse_armor |
| horsearmorgold | | golden_horse_armor |
| horsearmordiamond | | diamond_horse_armor |
| turtle_shell_piece | | scute |
| totem | | totem_of_undying |
| lodestonecompass | | lodestone_compass |
| map | | filled_map |
| emptymap | | empty_map |
| sign | | oak_sign |
| darkoak_sign | | dark_oak_sign |
| boat | 0 | oak_boat |
| boat | 1 | spruce_boat |
| boat | 2 | birch_boat |
| boat | 3 | jungle_boat |
| boat | 4 | acacia_boat |
| boat | 5 | dark_oak_boat |
| coal | 0 | coal |
| coal | 1 | charcoal |
| bucket | 0 | bucket |
| bucket | 1 | milk_bucket |
| bucket | 2 | cod_bucket |
| bucket | 3 | salmon_bucket |
| bucket | 4 | tropical_fish_bucket |
| bucket | 5 | pufferfish_bucket |
| bucket | 8 | water_bucket |
| bucket | 10 | lava_bucket |
| dye | 0 | ink_sac |
| dye | 1 | red_dye |
| dye | 2 | green_dye |
| dye | 3 | cocoa_beans |
| dye | 4 | lapis_lazuli |
| dye | 5 | purple_dye |
| dye | 6 | cyan_dye |
| dye | 7 | light_gray_dye |
| dye | 8 | gray_dye |
| dye | 9 | pink_dye |
| dye | 10 | lime_dye |
| dye | 11 | yellow_dye |
| dye | 12 | light_blue_dye |
| dye | 13 | magenta_dye |
| dye | 14 | orange_dye |
| dye | 15 | bone_meal |
| dye | 16 | black_dye |
| dye | 17 | brown_dye |
| dye | 18 | blue_dye |
| dye | 19 | white_dye |
| banner_pattern | 0 | creeper_banner_pattern |
| banner_pattern | 1 | skull_banner_pattern |
| banner_pattern | 2 | flower_banner_pattern |
| banner_pattern | 3 | mojang_banner_pattern |
| banner_pattern | 4 | field_masoned_banner_pattern |
| banner_pattern | 5 | bordure_indented_banner_pattern |
| banner_pattern | 6 | piglin_banner_pattern |
| spawn_egg | 10 | chicken_spawn_egg |
| spawn_egg | 11 | cow_spawn_egg |
| spawn_egg | 12 | pig_spawn_egg |
| spawn_egg | 13 | sheep_spawn_egg |
| spawn_egg | 14 | wolf_spawn_egg |
| spawn_egg | 15 | villager_spawn_egg |
| spawn_egg | 16 | mooshroom_spawn_egg |
| spawn_egg | 17 | squid_spawn_egg |
| spawn_egg | 18 | rabbit_spawn_egg |
| spawn_egg | 19 | bat_spawn_egg |
| spawn_egg | 22 | ocelot_spawn_egg |
| spawn_egg | 23 | horse_spawn_egg |
| spawn_egg | 24 | donkey_spawn_egg |
| spawn_egg | 25 | mule_spawn_egg |
| spawn_egg | 26 | skeleton_horse_spawn_egg |
| spawn_egg | 27 | zombie_horse_spawn_egg |
| spawn_egg | 28 | polar_bear_spawn_egg |
| spawn_egg | 29 | llama_spawn_egg |
| spawn_egg | 30 | parrot_spawn_egg |
| spawn_egg | 31 | dolphin_spawn_egg |
| spawn_egg | 32 | zombie_spawn_egg |
| spawn_egg | 33 | creeper_spawn_egg |
| spawn_egg | 34 | skeleton_spawn_egg |
| spawn_egg | 35 | spider_spawn_egg |
| spawn_egg | 36 | zombie_pigman_spawn_egg |
| spawn_egg | 37 | slime_spawn_egg |
| spawn_egg | 38 | enderman_spawn_egg |
| spawn_egg | 39 | silverfish_spawn_egg |
| spawn_egg | 40 | cave_spider_spawn_egg |
| spawn_egg | 41 | ghast_spawn_egg |
| spawn_egg | 42 | magma_cube_spawn_egg |
| spawn_egg | 43 | blaze_spawn_egg |
| spawn_egg | 44 | zombie_villager_spawn_egg |
| spawn_egg | 45 | witch_spawn_egg |
| spawn_egg | 46 | stray_spawn_egg |
| spawn_egg | 47 | husk_spawn_egg |
| spawn_egg | 48 | wither_skeleton_spawn_egg |
| spawn_egg | 49 | guardian_spawn_egg |
| spawn_egg | 50 | elder_guardian_spawn_egg |
| spawn_egg | 51 | npc_spawn_egg |
| spawn_egg | 54 | shulker_spawn_egg |
| spawn_egg | 55 | endermite_spawn_egg |
| spawn_egg | 56 | agent_spawn_egg |
| spawn_egg | 57 | vindicator_spawn_egg |
| spawn_egg | 58 | phantom_spawn_egg |
| spawn_egg | 59 | ravager_spawn_egg |
| spawn_egg | 74 | turtle_spawn_egg |
| spawn_egg | 75 | cat_spawn_egg |
| spawn_egg | 104 | evoker_spawn_egg |
| spawn_egg | 105 | vex_spawn_egg |
| spawn_egg | 108 | pufferfish_spawn_egg |
| spawn_egg | 109 | salmon_spawn_egg |
| spawn_egg | 110 | drowned_spawn_egg |
| spawn_egg | 111 | tropical_fish_spawn_egg |
| spawn_egg | 112 | cod_spawn_egg |
| spawn_egg | 113 | panda_spawn_egg |
| spawn_egg | 114 | pillager_spawn_egg |
| spawn_egg | 115 | villager_spawn_egg |
| spawn_egg | 116 | zombie_villager_spawn_egg |
| spawn_egg | 118 | wandering_trader_spawn_egg |
| spawn_egg | 121 | fox_spawn_egg |
| spawn_egg | 122 | bee_spawn_egg |
| spawn_egg | 123 | piglin_spawn_egg |
| spawn_egg | 124 | hoglin_spawn_egg |
| spawn_egg | 125 | strider_spawn_egg |
| spawn_egg | 126 | zoglin_spawn_egg |
| spawn_egg | 127 | piglin_brute_spawn_egg |
| spawn_egg | 128 | goat_spawn_egg |
| spawn_egg | 自定义生物 | 生物identifier_spawn_egg |

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB