“模组:制作指南/游戏基本架构”的版本间的差异
Margotbean(讨论 | 贡献) 小 (文本替换 - 替换“tt>”为“samp>”) |
|||
(未显示2个用户的3个中间版本) | |||
第1行: | 第1行: | ||
− | + | {{ 模组: 制作指南/header}} | |
− | 本页面将简单阐述部分游戏内的概念以帮助您制作模组。配合[[模组:常 | + | 本页面将简单阐述部分游戏内的概念以帮助您制作模组。配合[[模组:常 用方法|常见问题]]食用体验更佳。 |
==一些概念== | ==一些概念== | ||
第11行: | 第11行: | ||
===位置 (Positions)=== | ===位置 (Positions)=== | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 定位方式 | ! 定位方式 | ||
第19行: | 第19行: | ||
| 图块坐标 (tile position) | | 图块坐标 (tile position) | ||
| 地图左上角 | | 地图左上角 | ||
− | | 以'''[[#图块 (Tiles)|单元格]]'''为单位。通常用于物品放置,如:< | + | | 以'''[[#图块 (Tiles)|单元格]]'''为单位。通常用于物品放置,如:<samp>location.Objects</samp>。 |
|- | |- | ||
| 绝对坐标 (absolute position) | | 绝对坐标 (absolute position) | ||
第32行: | 第32行: | ||
换算: | 换算: | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
!colspan="3"| A → B | !colspan="3"| A → B | ||
第57行: | 第57行: | ||
===Net类型的数据 (Net fields)=== | ===Net类型的数据 (Net fields)=== | ||
− | 在源码中,有这样一种特殊的类型,它们都以< | + | 在源码中,有这样一种特殊的类型,它们都以<samp>Net</samp>作为前缀命名,因此得名'''net类型 (net type)'''。 |
在联机模式中,游戏正是通过这些net类型实现了'''在玩家之间同步数据'''。 | 在联机模式中,游戏正是通过这些net类型实现了'''在玩家之间同步数据'''。 | ||
− | 每隔一段时间,游戏便会从< | + | 每隔一段时间,游戏便会从<samp>Game1.netWorldState</samp>尽可能收集所有net数据,来与其他玩家同步。这表明,很多因模组做出的改变会自动被游戏同步。 |
− | 尽管net类型自带隐式转换,如:<code>bool x = new NetBool(true);</code>,但并不稳定,很可能会跟你所想达成的目标有出入,如:<code>item?.category == null</code>和<code>item?.category != null</code> 有可能会同时为< | + | 尽管net类型自带隐式转换,如:<code>bool x = new NetBool(true);</code>,但并不稳定,很可能会跟你所想达成的目标有出入,如:<code>item?.category == null</code>和<code>item?.category != null</code> 有可能会同时为<samp>true</samp>。 |
因此,请'''避免用net类型的隐式转换'''。具体如何拿到对应的值见下表: | 因此,请'''避免用net类型的隐式转换'''。具体如何拿到对应的值见下表: | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! net类型 | ! net类型 | ||
! 说明 | ! 说明 | ||
|- | |- | ||
− | | < | + | | <samp>NetBool</samp><br /><samp>NetColor</samp><br /><samp>NetFloat</samp><br /><samp>NetInt</samp><br /><samp>NetPoint</samp><br /><samp>NetString</samp> |
− | | 这些属于简单的net类型。通过< | + | | 这些属于简单的net类型。通过<samp>field.Value</samp>拿到对应值。 |
|- | |- | ||
− | | < | + | | <samp>NetCollection<T></samp><br /><samp>NetList<T></samp><br /><samp>NetObjectList<T></samp> |
− | | < | + | | <samp>T</samp>的集合。直接遍历 <code>foreach (T value in field)</code>。 |
|- | |- | ||
− | | < | + | | <samp>NetLongDictionary<TValue, TNetValue></samp><br /><samp>NetPointDictionary<TValue, TNetValue></samp><br /><samp>NetVector2Dictionary<TValue, TNetValue></samp> |
− | | 将< | + | | 将<samp>Long</samp>, <samp>Point</samp>, 或<samp>Vector2</samp> 类型的键映射至 <samp>TValue</samp> (原类型) 和 <samp>TNetValue</samp> (用于同步的net类型)。遍历键值对,如:<code>foreach (KeyValuePair<Long, TValue> pair in field.Pairs)</code>。 |
|} | |} | ||
第82行: | 第82行: | ||
玩家可以设置缩放等级,从75%到200%。这会影响屏幕上显示的像素大小。 | 玩家可以设置缩放等级,从75%到200%。这会影响屏幕上显示的像素大小。 | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 缩放至最小 (75%) | ! 缩放至最小 (75%) | ||
第92行: | 第92行: | ||
====对于SMAPI模组的影响==== | ====对于SMAPI模组的影响==== | ||
− | 缩放等级储存在< | + | 缩放等级储存在<samp>Game1.options.zoomLevel</samp>中。游戏会自动调整坐标绘制大小,很少有情况需要你亲自调整。万一有,你可以<samp>position * (1f / Game1.options.zoomLevel)</samp>手动调。 |
===UI缩放 (UI Scaling)=== | ===UI缩放 (UI Scaling)=== | ||
在1.5版本中,游戏加入了缩放UI的功能。这是一个独立于[[#缩放 (Zoom level)|上一节的缩放]]的新功能,特别用于缩放'''用户界面''',最小75%,最大150%。 | 在1.5版本中,游戏加入了缩放UI的功能。这是一个独立于[[#缩放 (Zoom level)|上一节的缩放]]的新功能,特别用于缩放'''用户界面''',最小75%,最大150%。 | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! UI最小显示 (75%) | ! UI最小显示 (75%) | ||
第111行: | 第111行: | ||
下表是游戏使用两种缩放模式的不同情景: | 下表是游戏使用两种缩放模式的不同情景: | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 情景 | ! 情景 | ||
! 缩放模式 | ! 缩放模式 | ||
|- | |- | ||
− | | [[模组:常 | + | | [[模组:常 用方法#菜单 (Active clickable menu)|菜单 (clickable menus)]] |
| UI模式 (通常) | | UI模式 (通常) | ||
|- | |- | ||
− | | [[模组:常 | + | | [[模组:常 用方法#HUD消息|HUD消息]] |
| UI模式 | | UI模式 | ||
|- | |- | ||
− | | [[模组:制作指南/APIs/Events#Display.RenderedActiveMenu|< | + | | [[模组:制作指南/APIs/Events#Display.RenderedActiveMenu|<samp>RenderingActiveMenu</samp>事件]]<br />[[模组:制作指南/APIs/Events#Display.RenderedActiveMenu|<samp>RenderedActiveMenu</samp>事件]] |
| UI模式 | | UI模式 | ||
|- | |- | ||
− | | [[模组:制作指南/APIs/Events#Display.Rendering|< | + | | [[模组:制作指南/APIs/Events#Display.Rendering|<samp>Rendering</samp>事件]]<br />[[模组:制作指南/APIs/Events#Display.Rendering|<samp>Rendered</samp>事件]] |
| 取决于具体上下文 | | 取决于具体上下文 | ||
|- | |- | ||
− | | < | + | | <samp>draw</samp>方法 |
| non-UI模式 | | non-UI模式 | ||
|- | |- | ||
第144行: | 第144行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | 在UI模式中,< | + | 在UI模式中,<samp>Game1.viewport</samp>通常可以替换成<samp>Game1.uiViewport</samp>。... // 未翻译 |
第151行: | 第151行: | ||
游戏主要逻辑。 下面是一些重要的成员: | 游戏主要逻辑。 下面是一些重要的成员: | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 字段、属性 | ! 字段、属性 | ||
第157行: | 第157行: | ||
! 描述 | ! 描述 | ||
|- | |- | ||
− | | < | + | | <samp>Game1.player</samp> |
− | | < | + | | <samp>Farmer</samp> |
| 当前玩家。 | | 当前玩家。 | ||
|- | |- | ||
− | | < | + | | <samp>Game1.currentLocation</samp> |
− | | < | + | | <samp>[[#GameLocation|GameLocation]]</samp> |
− | | 当前玩家所在的地点。 '''对于联机中客机玩家,在地点变化时可能为< | + | | 当前玩家所在的地点。 '''对于联机中客机玩家,在地点变化时可能为<samp>null</samp>。''' |
|- | |- | ||
− | | < | + | | <samp>Game1.locations</samp> |
− | | < | + | | <samp>IList<[[#GameLocation|GameLocation]]></samp> |
− | | 所有地点。'''对于联机中客机玩家,请使用[[Modding:Modder Guide/APIs/Multiplayer#Get_active_locations|SMAPI的< | + | | 所有地点。'''对于联机中客机玩家,请使用[[Modding:Modder Guide/APIs/Multiplayer#Get_active_locations|SMAPI的<samp>GetActiveLocations</samp>方法]]代替。''' |
|- | |- | ||
− | | < | + | | <samp>Game1.timeOfDay</samp><br /><samp>Game1.dayOfMonth</samp><br /><samp>Game1.currentSeason</samp><br /><samp>Game1.year</samp> |
− | | < | + | | <samp>int</samp><br /><samp>int</samp><br /><samp>string</samp><br /><samp>int</samp> |
| 当前时间、日期、季节、年份。另见[[Modding:Modder Guide/APIs/Utilities#Dates|SMAPI的日期工具类]]。 | | 当前时间、日期、季节、年份。另见[[Modding:Modder Guide/APIs/Utilities#Dates|SMAPI的日期工具类]]。 | ||
|- | |- | ||
− | | < | + | | <samp>Game1.itemsToShip</samp> |
− | | < | + | | <samp>IList<Item></samp> |
− | | 不要用这个,这是存档逻辑的一部分。请用< | + | | 不要用这个,这是存档逻辑的一部分。请用<samp>Game1.getFarm().getShippingBin(Farmer)</samp>。 |
|- | |- | ||
− | | < | + | | <samp>Game1.activeClickableMenu</samp> |
− | | < | + | | <samp>IClickableMenu</samp> |
| 当前显示的菜单。 | | 当前显示的菜单。 | ||
|} | |} | ||
第185行: | 第185行: | ||
表示地点,内有地图、物品、角色、动植物等等数据。下表是一些重要的成员: | 表示地点,内有地图、物品、角色、动植物等等数据。下表是一些重要的成员: | ||
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 字段、属性 | ! 字段、属性 | ||
第191行: | 第191行: | ||
! 描述 | ! 描述 | ||
|- | |- | ||
− | | < | + | | <samp>Name</samp> |
− | | < | + | | <samp>string</samp> |
− | | 唯一名称。(这对于建筑室内并不唯一,见< | + | | 唯一名称。(这对于建筑室内并不唯一,见<samp>uniqueName</samp>。) |
|- | |- | ||
− | | < | + | | <samp>IsFarm</samp> |
− | | < | + | | <samp>bool</samp> |
| 是否为农场(农场内可种植作物)。 | | 是否为农场(农场内可种植作物)。 | ||
|- | |- | ||
− | | < | + | | <samp>IsGreenhouse</samp> |
− | | < | + | | <samp>bool</samp> |
| 是否为温室(温室内可种植作物,且全年可生长)。 | | 是否为温室(温室内可种植作物,且全年可生长)。 | ||
|- | |- | ||
− | | < | + | | <samp>IsOutdoors</samp> |
− | | < | + | | <samp>bool</samp> |
| 是否为室外。 | | 是否为室外。 | ||
|- | |- | ||
− | | < | + | | <samp>characters</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetCollection</samp>]] of <samp>NPC</samp> |
| 该地点中的村民、宠物、马、怪物。 | | 该地点中的村民、宠物、马、怪物。 | ||
|- | |- | ||
− | | < | + | | <samp>critters</samp> (private) |
− | | < | + | | <samp>List</samp> of <samp>Critter</samp> |
| 该地点中暂时的鸟、松鼠等等,用于衬托景色。 | | 该地点中暂时的鸟、松鼠等等,用于衬托景色。 | ||
|- | |- | ||
− | | < | + | | <samp>debris</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetCollection</samp>]] of <samp>Debris</samp> |
| 掉落物(漂浮的物品)。 | | 掉落物(漂浮的物品)。 | ||
|- | |- | ||
− | | < | + | | <samp>farmers</samp> |
− | | < | + | | <samp>FarmerCollection</samp> |
| 该地点中的玩家。 | | 该地点中的玩家。 | ||
|- | |- | ||
− | | < | + | | <samp>Objects</samp> |
− | | < | + | | <samp>OverlaidDictionary</samp> |
− | | 该地点中所有物品。(< | + | | 该地点中所有物品。(<samp>OverlaidDictionary</samp>实际上是一个[[#Net类型的数据 (Net fields)|<samp>NetVector2Dictionary</samp>]],并额外增加了show certain quest items over pre-existing objects 的逻辑。) |
|- | |- | ||
− | | < | + | | <samp>terrainFeatures</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetVector2Dictionary</samp>]] of <samp>TerrainFeature</samp> |
| 该地点中的树、果树、草、泥土地(其中包括农作物)、地板等等。 | | 该地点中的树、果树、草、泥土地(其中包括农作物)、地板等等。 | ||
|- | |- | ||
− | | < | + | | <samp>waterTiles</samp> |
− | | < | + | | <samp>bool[,]</samp> |
| 一个多维数组表示地图图块是否为代表河/湖。如:<code>if (location.waterTiles[10, 20])</code>将检查坐标为(10, 20)的图块。 | | 一个多维数组表示地图图块是否为代表河/湖。如:<code>if (location.waterTiles[10, 20])</code>将检查坐标为(10, 20)的图块。 | ||
|} | |} | ||
====BuildableGameLocation==== | ====BuildableGameLocation==== | ||
− | < | + | <samp>GameLocation</samp>的子类。表示'''支持建造建筑'''的地点。原版游戏中,只有<samp>Farm</samp>是<samp>BuildableGameLocation</samp>。下面是一些重要的成员: |
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 字段 | ! 字段 | ||
第245行: | 第245行: | ||
! 描述 | ! 描述 | ||
|- | |- | ||
− | | < | + | | <samp>buildings</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetCollection</samp>]] of <samp>Building</samp> |
| 该地点中的建筑。 | | 该地点中的建筑。 | ||
|} | |} | ||
====Farm==== | ====Farm==== | ||
− | < | + | <samp>GameLocation</samp>和<samp>BuildableGameLocation</samp>的子类。玩家可在农场中养动物、种庄稼。原版游戏中,Farm类型的实例地点只有一个(<samp>Game1.getFarm();</samp>)。下面是一些重要的成员: |
− | {| class="wikitable" | + | {|class="wikitable" |
|- | |- | ||
! 字段、属性 | ! 字段、属性 | ||
第259行: | 第259行: | ||
! 描述 | ! 描述 | ||
|- | |- | ||
− | | < | + | | <samp>animals</samp> |
− | | [[#Net fields|< | + | | [[#Net fields|<samp>NetLongDictionary</samp>]] of <samp>FarmAnimal</samp> |
| The farm animals currently in the location. | | The farm animals currently in the location. | ||
|- | |- | ||
− | | < | + | | <samp>resourceClumps</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetCollection</samp>]] of <samp>ResourceClump</samp> |
| 该地点中的巨大作物、木桩、大石块、陨石。 | | 该地点中的巨大作物、木桩、大石块、陨石。 | ||
|- | |- | ||
− | | < | + | | <samp>piecesOfHay</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetInt</samp>]] |
| 筒仓中储存的稻草数量。 | | 筒仓中储存的稻草数量。 | ||
|- | |- | ||
− | | < | + | | <samp>shippingBin</samp> |
− | | [[#Net类型的数据 (Net fields)|< | + | | [[#Net类型的数据 (Net fields)|<samp>NetCollection</samp>]] of <samp>Item</samp> |
| 出货箱里的物品。 | | 出货箱里的物品。 | ||
|} | |} | ||
[[en:Modding:Modder Guide/Game Fundamentals]] | [[en:Modding:Modder Guide/Game Fundamentals]] |
2021年11月4日 (四) 19:11的最新版本
← 模组:目录
本页面将简单阐述部分游戏内的概念以帮助您制作模组。配合常见问题食用体验更佳。
一些概念
图块 (Tiles)
星露谷是由一个个图块组成的。我们又为它们定义了自己的坐标,如 (0, 0)表示左上角。横坐标越往右值越大,纵坐标越往下值越大。
位置 (Positions)
定位方式 | 参照点 | 解释 |
---|---|---|
图块坐标 (tile position) | 地图左上角 | 以单元格为单位。通常用于物品放置,如:location.Objects。 |
绝对坐标 (absolute position) | 地图左上角 | 以像素为单位。用于更精确的测量,如:NPC的位置。 |
相对于屏幕的坐标 (screen position) | 可见(visible) 的屏幕的左上角 | 以像素为单位。通常用于绘制。 |
换算:
A → B | 公式 | ||
---|---|---|---|
absolute | → | screen | x - Game1.viewport.X, y - Game1.viewport.Y
|
absolute | → | tile | x / Game1.tileSize, y / Game1.tileSize
|
screen | → | absolute | x + Game1.viewport.X, y + Game1.viewport.Y
|
screen | → | tile | (x + Game1.viewport.X) / Game1.tileSize, (y + Game1.viewport.Y) / Game1.tileSize
|
tile | → | absolute | x * Game1.tileSize, y * Game1.tileSize
|
tile | → | screen | (x * Game1.tileSize) - Game1.viewport.X, (y * Game1.tileSize) - Game1.viewport.Y
|
Net类型的数据 (Net fields)
在源码中,有这样一种特殊的类型,它们都以Net作为前缀命名,因此得名net类型 (net type)。 在联机模式中,游戏正是通过这些net类型实现了在玩家之间同步数据。 每隔一段时间,游戏便会从Game1.netWorldState尽可能收集所有net数据,来与其他玩家同步。这表明,很多因模组做出的改变会自动被游戏同步。
尽管net类型自带隐式转换,如:bool x = new NetBool(true);
,但并不稳定,很可能会跟你所想达成的目标有出入,如:item?.category == null
和item?.category != null
有可能会同时为true。
因此,请避免用net类型的隐式转换。具体如何拿到对应的值见下表:
net类型 | 说明 |
---|---|
NetBool NetColor NetFloat NetInt NetPoint NetString |
这些属于简单的net类型。通过field.Value拿到对应值。 |
NetCollection<T> NetList<T> NetObjectList<T> |
T的集合。直接遍历 foreach (T value in field) 。
|
NetLongDictionary<TValue, TNetValue> NetPointDictionary<TValue, TNetValue> NetVector2Dictionary<TValue, TNetValue> |
将Long, Point, 或Vector2 类型的键映射至 TValue (原类型) 和 TNetValue (用于同步的net类型)。遍历键值对,如:foreach (KeyValuePair<Long, TValue> pair in field.Pairs) 。
|
缩放 (Zoom level)
玩家可以设置缩放等级,从75%到200%。这会影响屏幕上显示的像素大小。
缩放至最小 (75%) | 缩放至最大 (200%) |
---|---|
对于SMAPI模组的影响
缩放等级储存在Game1.options.zoomLevel中。游戏会自动调整坐标绘制大小,很少有情况需要你亲自调整。万一有,你可以position * (1f / Game1.options.zoomLevel)手动调。
UI缩放 (UI Scaling)
在1.5版本中,游戏加入了缩放UI的功能。这是一个独立于上一节的缩放的新功能,特别用于缩放用户界面,最小75%,最大150%。
UI最小显示 (75%) | UI最大显示 (150%) |
---|---|
对于SMAPI模组的影响
游戏有两种缩放模式,UI 和 non-UI。当前模式储存在Game1.uiMode
中。不要将两种模式混淆,这会带来复杂的计算。
下表是游戏使用两种缩放模式的不同情景:
情景 | 缩放模式 |
---|---|
菜单 (clickable menus) | UI模式 (通常) |
HUD消息 | UI模式 |
RenderingActiveMenu事件 RenderedActiveMenu事件 |
UI模式 |
Rendering事件 Rendered事件 |
取决于具体上下文 |
draw方法 | non-UI模式 |
tile (non-pixel) coordinates | 不受UI缩放影响 |
当游戏不在UI模式中,而你又想绘制UI时,请手动设置:
Game1.game1.InUIMode(() =>
{
// ...
});
在UI模式中,Game1.viewport通常可以替换成Game1.uiViewport。... // 未翻译
主要的类
Game1
游戏主要逻辑。 下面是一些重要的成员:
字段、属性 | 类型 | 描述 |
---|---|---|
Game1.player | Farmer | 当前玩家。 |
Game1.currentLocation | GameLocation | 当前玩家所在的地点。 对于联机中客机玩家,在地点变化时可能为null。 |
Game1.locations | IList<GameLocation> | 所有地点。对于联机中客机玩家,请使用SMAPI的GetActiveLocations方法代替。 |
Game1.timeOfDay Game1.dayOfMonth Game1.currentSeason Game1.year |
int int string int |
当前时间、日期、季节、年份。另见SMAPI的日期工具类。 |
Game1.itemsToShip | IList<Item> | 不要用这个,这是存档逻辑的一部分。请用Game1.getFarm().getShippingBin(Farmer)。 |
Game1.activeClickableMenu | IClickableMenu | 当前显示的菜单。 |
GameLocation
表示地点,内有地图、物品、角色、动植物等等数据。下表是一些重要的成员:
字段、属性 | 类型 | 描述 |
---|---|---|
Name | string | 唯一名称。(这对于建筑室内并不唯一,见uniqueName。) |
IsFarm | bool | 是否为农场(农场内可种植作物)。 |
IsGreenhouse | bool | 是否为温室(温室内可种植作物,且全年可生长)。 |
IsOutdoors | bool | 是否为室外。 |
characters | NetCollection of NPC | 该地点中的村民、宠物、马、怪物。 |
critters (private) | List of Critter | 该地点中暂时的鸟、松鼠等等,用于衬托景色。 |
debris | NetCollection of Debris | 掉落物(漂浮的物品)。 |
farmers | FarmerCollection | 该地点中的玩家。 |
Objects | OverlaidDictionary | 该地点中所有物品。(OverlaidDictionary实际上是一个NetVector2Dictionary,并额外增加了show certain quest items over pre-existing objects 的逻辑。) |
terrainFeatures | NetVector2Dictionary of TerrainFeature | 该地点中的树、果树、草、泥土地(其中包括农作物)、地板等等。 |
waterTiles | bool[,] | 一个多维数组表示地图图块是否为代表河/湖。如:if (location.waterTiles[10, 20]) 将检查坐标为(10, 20)的图块。
|
BuildableGameLocation
GameLocation的子类。表示支持建造建筑的地点。原版游戏中,只有Farm是BuildableGameLocation。下面是一些重要的成员:
字段 | 类型 | 描述 |
---|---|---|
buildings | NetCollection of Building | 该地点中的建筑。 |
Farm
GameLocation和BuildableGameLocation的子类。玩家可在农场中养动物、种庄稼。原版游戏中,Farm类型的实例地点只有一个(Game1.getFarm();)。下面是一些重要的成员:
字段、属性 | 类型 | 描述 |
---|---|---|
animals | NetLongDictionary of FarmAnimal | The farm animals currently in the location. |
resourceClumps | NetCollection of ResourceClump | 该地点中的巨大作物、木桩、大石块、陨石。 |
piecesOfHay | NetInt | 筒仓中储存的稻草数量。 |
shippingBin | NetCollection of Item | 出货箱里的物品。 |