模组:制作指南/游戏基本架构

来自Stardew Valley Wiki
跳到导航 跳到搜索

制作SMAPI模组 SMAPI mascot.png


模组:目录

本页面将简单阐述部分游戏内的概念以帮助您制作模组。配合常见问题食用体验更佳。

一些概念

时间格式

游戏内时间采用一种特殊的24小时制,暂且称为“26小时制”,按10分钟为步长计时。这也是C# modContent Patcher包所使用的格式。

样例时间

时间值 显示文本
600 6:00 am
1250 12:50 am
1300 1:00 pm
2600 2:00 am (睡前)

内部时间在睡觉之前都会一直增加(例如,次日6时会在这种情况下变为3000)。


地块

星露谷是由一个个地块(tile,或称图块)组成的。我们又为它们定义了自己的坐标,如 (0, 0)表示左上角。横坐标越往右值越大,纵坐标越往下值越大。

Modding - creating an XNB mod - tile coordinates.png

位置 (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 == nullitem?.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%)
Zoom level 75.png Zoom level 200.png

对于SMAPI模组的影响

缩放等级储存在Game1.options.zoomLevel中。游戏会自动调整坐标绘制大小,很少有情况需要你亲自调整。万一有,你可以position * (1f / Game1.options.zoomLevel)手动调。

UI缩放 (UI Scaling)

在1.5版本中,游戏加入了缩放UI的功能。这是一个独立于上一节的缩放的新功能,特别用于缩放用户界面,最小75%,最大150%。

UI最小显示 (75%) UI最大显示 (150%)
UI scale 75.png UI scale 150.png

对于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 et al

表示地点,内有地图、物品、角色、动植物等等数据。下表是一些重要的成员:

字段、属性 类型 描述
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的子类。表示支持建造建筑的地点。原版游戏中,只有FarmBuildableGameLocation。下面是一些重要的成员:

字段 类型 描述
buildings NetCollection of Building 该地点中的建筑。

Farm

GameLocationBuildableGameLocation的子类。玩家可在农场中养动物、种庄稼。原版游戏中,Farm类型的实例地点只有一个(Game1.getFarm();)。下面是一些重要的成员:

字段、属性 类型 描述
animals NetLongDictionary of FarmAnimal The farm animals currently in the location.
resourceClumps NetCollection of ResourceClump 该地点中的巨大作物、木桩、大石块、陨石。
piecesOfHay NetInt 筒仓中储存的稻草数量。
shippingBin NetCollection of Item 出货箱里的物品。