Изменения

Перейти к навигации Перейти к поиску
Нет описания правки
Строка 21: Строка 21:  
| tile position
 
| tile position
 
| top-left corner of the map
 
| top-left corner of the map
| measured in [[#Tiles|tiles]]; used when placing things on the map (e.g. <tt>location.Objects</tt> uses tile positions).
+
| measured in [[#Tiles|tiles]]; used when placing things on the map (''e.g.,'' <samp>location.Objects</samp> uses tile positions).
 
|-
 
|-
 
| absolute position
 
| absolute position
 
| top-left corner of the map
 
| top-left corner of the map
| measured in pixels; used when more granular measurements are needed (e.g. NPC movement).
+
| measured in pixels; used when more granular measurements are needed (''e.g.,'' NPC movement).
 
|-
 
|-
 
| screen position
 
| screen position
Строка 59: Строка 59:     
===Net fields===
 
===Net fields===
A 'net type' is any of several classes which Stardew Valley uses to sync data between players, and a 'net field' is any field or property of those types. They're named for the <code>Net</code> prefix in their type names. Net types can represent simple values like <tt>NetBool</tt>, or complex values like <tt>NetFieldDictionary</tt>. The game will regularly collect all the net fields reachable from <tt>Game1.netWorldState</tt> and sync them with other players. That means that many mod changes will be synchronised automatically in multiplayer.
+
A 'net type' is any of several classes which Stardew Valley uses to sync data between players, and a 'net field' is any field or property of those types. They're named for the <code>Net</code> prefix in their type names. Net types can represent simple values like <samp>NetBool</samp>, or complex values like <samp>NetFieldDictionary</samp>. The game will regularly collect all the net fields reachable from <samp>Game1.netWorldState</samp> and sync them with other players. That means that many mod changes will be synchronised automatically in multiplayer.
   −
Although net fields can be implicitly converted to an equivalent value type (like <code>bool x = new NetBool(true)</code>), their conversion rules are counterintuitive and error-prone (e.g. <code>item?.category == null && item?.category != null</code> can both be true at once). To avoid bugs, never implicitly cast net fields; access the underlying value directly instead. The build config NuGet package should detect most implicit conversions and show an appropriate build warning.
+
Although net fields can be implicitly converted to an equivalent value type (like <code>bool x = new NetBool(true)</code>), their conversion rules are counterintuitive and error-prone (''e.g.,'' <code>item?.category == null && item?.category != null</code> can both be true at once). To avoid bugs, never implicitly cast net fields; access the underlying value directly instead. The build config NuGet package should detect most implicit conversions and show an appropriate build warning.
    
Here's how to access the data in some common net types:
 
Here's how to access the data in some common net types:
Строка 69: Строка 69:  
! description
 
! description
 
|-
 
|-
| <tt>NetBool</tt><br /><tt>NetColor</tt><br /><tt>NetFloat</tt><br /><tt>NetInt</tt><br /><tt>NetPoint</tt><br /><tt>NetString</tt>
+
| <samp>NetBool</samp><br /><samp>NetColor</samp><br /><samp>NetFloat</samp><br /><samp>NetInt</samp><br /><samp>NetPoint</samp><br /><samp>NetString</samp>
| A simple synchronised value. Access the value using <tt>field.Value</tt>.
+
| A simple synchronised value. Access the value using <samp>field.Value</samp>.
 
|-
 
|-
| <tt>NetCollection&lt;T&gt;</tt><br /><tt>NetList&lt;T&gt;</tt><br /><tt>NetObjectList&lt;T&gt;</tt>
+
| <samp>NetCollection&lt;T&gt;</samp><br /><samp>NetList&lt;T&gt;</samp><br /><samp>NetObjectList&lt;T&gt;</samp>
| A list of <tt>T</tt> values. This implements the standard interfaces like [https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 <tt>IEnumerable&lt;T&gt;</tt>] and [https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ilist-1 <tt>IList&lt;T&gt;</tt>], so you can iterate it directly like <code>foreach (T value in field)</code>.
+
| A list of <samp>T</samp> values. This implements the standard interfaces like [https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1 <samp>IEnumerable&lt;T&gt;</samp>] and [https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ilist-1 <samp>IList&lt;T&gt;</samp>], so you can iterate it directly like <code>foreach (T value in field)</code>.
 
|-
 
|-
| <tt>NetLongDictionary&lt;TValue, TNetValue&gt;</tt><br /><tt>NetPointDictionary&lt;TValue, TNetValue&gt;</tt><br /><tt>NetVector2Dictionary&lt;TValue, TNetValue&gt;</tt>
+
| <samp>NetLongDictionary&lt;TValue, TNetValue&gt;</samp><br /><samp>NetPointDictionary&lt;TValue, TNetValue&gt;</samp><br /><samp>NetVector2Dictionary&lt;TValue, TNetValue&gt;</samp>
| Maps <tt>Long</tt>, <tt>Point</tt>, or <tt>Vector2</tt> keys to instances of <tt>TValue</tt> (the underlying value type) and <tt>TNetValue</tt> (the synchronised net type). You can iterate key/value pairs like <code>foreach (KeyValuePair<Long, TValue> pair in field.Pairs)</code> (replacing <tt>Long</tt> with <tt>Point</tt> or <tt>Vector2</tt> if needed).
+
| Maps <samp>Long</samp>, <samp>Point</samp>, or <samp>Vector2</samp> keys to instances of <samp>TValue</samp> (the underlying value type) and <samp>TNetValue</samp> (the synchronised net type). You can iterate key/value pairs like <code>foreach (KeyValuePair<Long, TValue> pair in field.Pairs)</code> (replacing <samp>Long</samp> with <samp>Point</samp> or <samp>Vector2</samp> if needed).
 
|}
 
|}
   Строка 92: Строка 92:     
; Effect on SMAPI mods
 
; Effect on SMAPI mods
: In game code, this is represented by the <tt>Game1.options.zoomLevel</tt> field. Coordinates are generally adjusted for zoom level automatically, so you rarely need to account for this; but you can convert an unadjusted coordinate using <code>position * (1f / Game1.options.zoomLevel)</code> if needed.
+
: In game code, this is represented by the <samp>Game1.options.zoomLevel</samp> field. Coordinates are generally adjusted for zoom level automatically, so you rarely need to account for this; but you can convert an unadjusted coordinate using <code>position * (1f / Game1.options.zoomLevel)</code> if needed.
    
===UI scaling===
 
===UI scaling===
Строка 107: Строка 107:     
; Effect on SMAPI mods
 
; Effect on SMAPI mods
: The game has two distinct scaling modes depending on the context: ''UI mode'' and ''non-UI mode''. You can check <tt>Game1.uiMode</tt> to know which mode is active. You should be careful not to mix UI and non-UI coordinates to avoid tricky calculations; for example, do all your work in one coordinate system and then convert them once.
+
: The game has two distinct scaling modes depending on the context: ''UI mode'' and ''non-UI mode''. You can check <samp>Game1.uiMode</samp> to know which mode is active. You should be careful not to mix UI and non-UI coordinates to avoid tricky calculations; for example, do all your work in one coordinate system and then convert them once.
    
: A quick reference of common scenarios:
 
: A quick reference of common scenarios:
Строка 121: Строка 121:  
| UI mode
 
| UI mode
 
|-
 
|-
| [[Modding:Modder Guide/APIs/Events#Display.RenderingActiveMenu|<tt>RenderingActiveMenu</tt>]]<br />[[Modding:Modder Guide/APIs/Events#Display.RenderedActiveMenu|<tt>RenderedActiveMenu</tt>]]
+
| [[Modding:Modder Guide/APIs/Events#Display.RenderingActiveMenu|<samp>RenderingActiveMenu</samp>]]<br />[[Modding:Modder Guide/APIs/Events#Display.RenderedActiveMenu|<samp>RenderedActiveMenu</samp>]]
 
| UI mode
 
| UI mode
 
|-
 
|-
| [[Modding:Modder Guide/APIs/Events#Display.Rendering|<tt>Rendering</tt>]]<br />[[Modding:Modder Guide/APIs/Events#Display.Rendering|<tt>Rendered</tt>]]
+
| [[Modding:Modder Guide/APIs/Events#Display.Rendering|<samp>Rendering</samp>]]<br />[[Modding:Modder Guide/APIs/Events#Display.Rendering|<samp>Rendered</samp>]]
| depends on the context; check <tt>Game1.uiMode</tt>
+
| depends on the context; check <samp>Game1.uiMode</samp>
 
|-
 
|-
| <tt>draw</tt> method for world objects
+
| <samp>draw</samp> method for world objects
 
| non-UI mode
 
| non-UI mode
 
|-
 
|-
Строка 141: Строка 141:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
: In UI mode, you should usually replace <tt>Game1.viewport</tt> with <tt>Game1.uiViewport</tt>. '''Don't''' do this if you'll adjust the positions for UI scaling separately, since double-conversion will give you incorrect results. You can convert between UI and non-UI coordinates using <tt>Utility.ModifyCoordinatesForUIScale</tt> and <tt>Utility.ModifyCoordinatesFromUIScale</tt>.
+
: In UI mode, you should usually replace <samp>Game1.viewport</samp> with <samp>Game1.uiViewport</samp>. '''Don't''' do this if you'll adjust the positions for UI scaling separately, since double-conversion will give you incorrect results. You can convert between UI and non-UI coordinates using <samp>Utility.ModifyCoordinatesForUIScale</samp> and <samp>Utility.ModifyCoordinatesFromUIScale</samp>.
   −
: You can test whether your mod accounts for this correctly by setting the zoom to maximum and the UI scale to minimum (i.e. have them at opposite values) or vice versa; in particular check any logic which handles pixel positions, like menus clicking.
+
: You can test whether your mod accounts for this correctly by setting the zoom to maximum and the UI scale to minimum (''i.e.,'' have them at opposite values) or vice versa; in particular check any logic which handles pixel positions, like menus clicking.
    
==Main classes==
 
==Main classes==
 
===Game1===
 
===Game1===
<tt>Game1</tt> is the game's core logic. Most of the game state is tracked through this class. Here are some of the most useful fields:
+
<samp>Game1</samp> is the game's core logic. Most of the game state is tracked through this class. Here are some of the most useful fields:
    
{|class="wikitable"
 
{|class="wikitable"
Строка 155: Строка 155:  
! purpose
 
! purpose
 
|-
 
|-
| <tt>Game1.player</tt>
+
| <samp>Game1.player</samp>
| <tt>Farmer</tt>
+
| <samp>Farmer</samp>
 
| The current player.
 
| The current player.
 
|-
 
|-
| <tt>Game1.currentLocation</tt>
+
| <samp>Game1.currentLocation</samp>
| <tt>[[#GameLocation|GameLocation]]</tt>
+
| <samp>[[#GameLocation|GameLocation]]</samp>
| The game location containing the current player. '''For a non-main player, may be <tt>null</tt> when transitioning between locations.'''
+
| The game location containing the current player. '''For a non-main player, may be <samp>null</samp> when transitioning between locations.'''
 
|-
 
|-
| <tt>Game1.locations</tt>
+
| <samp>Game1.locations</samp>
| <tt>IList&lt;[[#GameLocation|GameLocation]]&gt;</tt>
+
| <samp>IList&lt;[[#GameLocation|GameLocation]]&gt;</samp>
| All locations in the game. '''For a non-main player, use [[Modding:Modder Guide/APIs/Multiplayer#Get_active_locations|SMAPI's <tt>GetActiveLocations</tt> method]] instead.'''
+
| All locations in the game. '''For a non-main player, use [[Modding:Modder Guide/APIs/Multiplayer#Get_active_locations|SMAPI's <samp>GetActiveLocations</samp> method]] instead.'''
 
|-
 
|-
| <tt>Game1.timeOfDay</tt><br /><tt>Game1.dayOfMonth</tt><br /><tt>Game1.currentSeason</tt><br /><tt>Game1.year</tt>
+
| <samp>Game1.timeOfDay</samp><br /><samp>Game1.dayOfMonth</samp><br /><samp>Game1.currentSeason</samp><br /><samp>Game1.year</samp>
| <tt>int</tt><br /><tt>int</tt><br /><tt>string</tt><br /><tt>int</tt>
+
| <samp>int</samp><br /><samp>int</samp><br /><samp>string</samp><br /><samp>int</samp>
 
| The current time, day, season, and year. See also [[Modding:Modder Guide/APIs/Utilities#Dates|SMAPI's date utility]].
 
| The current time, day, season, and year. See also [[Modding:Modder Guide/APIs/Utilities#Dates|SMAPI's date utility]].
 
|-
 
|-
| <tt>Game1.itemsToShip</tt>
+
| <samp>Game1.itemsToShip</samp>
| <tt>IList&lt;Item&gt;</tt>
+
| <samp>IList&lt;Item&gt;</samp>
| Do not use (this is part of the save logic). See <tt>Game1.getFarm().getShippingBin(Farmer)</tt> instead.
+
| Do not use (this is part of the save logic). See <samp>Game1.getFarm().getShippingBin(Farmer)</samp> instead.
 
|-
 
|-
| <tt>Game1.activeClickableMenu</tt>
+
| <samp>Game1.activeClickableMenu</samp>
| <tt>IClickableMenu</tt>
+
| <samp>IClickableMenu</samp>
| The modal menu being displayed. Creating an <tt>IClickableMenu</tt> subclass and assigning an instance to this field will display it.
+
| The modal menu being displayed. Creating an <samp>IClickableMenu</samp> subclass and assigning an instance to this field will display it.
 
|}
 
|}
    
===<span id="GameLocation"></span>GameLocation et al===
 
===<span id="GameLocation"></span>GameLocation et al===
 
<ul>
 
<ul>
<li><tt>GameLocation</tt> represents an in-game location players can visit. Each location has a map (the tile layout), objects, trees, characters, etc. Here are some of the most useful fields for any location:
+
<li><samp>GameLocation</samp> represents an in-game location players can visit. Each location has a map (the tile layout), objects, trees, characters, etc. Here are some of the most useful fields for any location:
    
{|class="wikitable"
 
{|class="wikitable"
Строка 190: Строка 190:  
! purpose
 
! purpose
 
|-
 
|-
| <tt>Name</tt>
+
| <samp>Name</samp>
| <tt>string</tt>
+
| <samp>string</samp>
| The unique name for this location. (This isn't unique for constructed building interiors like cabins; see <tt>uniqueName</tt> instead.)
+
| The unique name for this location. (This isn't unique for constructed building interiors like cabins; see <samp>uniqueName</samp> instead.)
 
|-
 
|-
| <tt>IsFarm</tt>
+
| <samp>IsFarm</samp>
| <tt>bool</tt>
+
| <samp>bool</samp>
 
| Whether this is a farm, where crops can be planted.
 
| Whether this is a farm, where crops can be planted.
 
|-
 
|-
| <tt>IsGreenhouse</tt>
+
| <samp>IsGreenhouse</samp>
| <tt>bool</tt>
+
| <samp>bool</samp>
 
| Whether this is a greenhouse, where crops can be planted and grown all year.
 
| Whether this is a greenhouse, where crops can be planted and grown all year.
 
|-
 
|-
| <tt>IsOutdoors</tt>
+
| <samp>IsOutdoors</samp>
| <tt>bool</tt>
+
| <samp>bool</samp>
 
| Whether the location is outdoors (as opposed to a greenhouse, building, etc).
 
| Whether the location is outdoors (as opposed to a greenhouse, building, etc).
 
|-
 
|-
| <tt>characters</tt>
+
| <samp>characters</samp>
| [[#Net fields|<tt>NetCollection</tt>]] of <tt>NPC</tt>
+
| [[#Net fields|<samp>NetCollection</samp>]] of <samp>NPC</samp>
 
| The villagers, pets, horses, and monsters in the location.
 
| The villagers, pets, horses, and monsters in the location.
 
|-
 
|-
| <tt>critters</tt> (private)
+
| <samp>critters</samp> (private)
| <tt>List</tt> of <tt>Critter</tt>
+
| <samp>List</samp> of <samp>Critter</samp>
 
| The temporary birds, squirrels, or other critters in the location.
 
| The temporary birds, squirrels, or other critters in the location.
 
|-
 
|-
| <tt>debris</tt>
+
| <samp>debris</samp>
| [[#Net fields|<tt>NetCollection</tt>]] of <tt>Debris</tt>
+
| [[#Net fields|<samp>NetCollection</samp>]] of <samp>Debris</samp>
 
| The floating items in the location.
 
| The floating items in the location.
 
|-
 
|-
| <tt>farmers</tt>
+
| <samp>farmers</samp>
| <tt>FarmerCollection</tt>
+
| <samp>FarmerCollection</samp>
 
| The players in the location.
 
| The players in the location.
 
|-
 
|-
| <tt>Objects</tt>
+
| <samp>Objects</samp>
| <tt>OverlaidDictionary</tt>
+
| <samp>OverlaidDictionary</samp>
| The placed fences, crafting machines, and other objects in the current location. (<tt>OverlaidDictionary</tt> is basically a [[#Net fields|<tt>NetVector2Dictionary</tt>]] with logic added to show certain quest items over pre-existing objects.)
+
| The placed fences, crafting machines, and other objects in the current location. (<samp>OverlaidDictionary</samp> is basically a [[#Net fields|<samp>NetVector2Dictionary</samp>]] with logic added to show certain quest items over pre-existing objects.)
 
|-
 
|-
| <tt>terrainFeatures</tt>
+
| <samp>terrainFeatures</samp>
| [[#Net fields|<tt>NetVector2Dictionary</tt>]] of <tt>TerrainFeature</tt>
+
| [[#Net fields|<samp>NetVector2Dictionary</samp>]] of <samp>TerrainFeature</samp>
 
| The trees, fruit trees, tall grass, tilled dirt (including crops), and flooring in the location. For each pair, the key is their tile position and the value is the terrain feature instance.
 
| The trees, fruit trees, tall grass, tilled dirt (including crops), and flooring in the location. For each pair, the key is their tile position and the value is the terrain feature instance.
 
|-
 
|-
| <tt>waterTiles</tt>
+
| <samp>waterTiles</samp>
| <tt>bool[,]</tt>
+
| <samp>bool[,]</samp>
 
| A multi-dimensional array which indicates whether each tile on the map is a lake/river tile. For example, <code>if (location.waterTiles[10, 20])</code> checks the tile at [[#Tiles|position]] (10, 20).
 
| A multi-dimensional array which indicates whether each tile on the map is a lake/river tile. For example, <code>if (location.waterTiles[10, 20])</code> checks the tile at [[#Tiles|position]] (10, 20).
 
|}</li>
 
|}</li>
   −
<li><tt>BuildableGameLocation</tt> is a subclass of <tt>GameLocation</tt> for locations where players can construct buildings. In the vanilla game, only the farm is a buildable location. Here are the most useful fields:
+
<li><samp>BuildableGameLocation</samp> is a subclass of <samp>GameLocation</samp> for locations where players can construct buildings. In the vanilla game, only the farm is a buildable location. Here are the most useful fields:
    
{|class="wikitable"
 
{|class="wikitable"
Строка 243: Строка 243:  
! purpose
 
! purpose
 
|-
 
|-
| <tt>buildings</tt>
+
| <samp>buildings</samp>
| [[#Net fields|<tt>NetCollection</tt>]] of <tt>Building</tt>
+
| [[#Net fields|<samp>NetCollection</samp>]] of <samp>Building</samp>
 
| The buildings in the location.
 
| The buildings in the location.
 
|}</li>
 
|}</li>
   −
<li><tt>Farm</tt> is a subclass of both <tt>GameLocation</tt> and <tt>BuildableGameLocation</tt> for locations where the player can have animals and grow crops. In the vanilla, there's only one farm location (accessed using <code>Game1.getFarm()</code>). Here are its most useful properties:
+
<li><samp>Farm</samp> is a subclass of both <samp>GameLocation</samp> and <samp>BuildableGameLocation</samp> for locations where the player can have animals and grow crops. In the vanilla, there's only one farm location (accessed using <code>Game1.getFarm()</code>). Here are its most useful properties:
    
{|class="wikitable"
 
{|class="wikitable"
Строка 256: Строка 256:  
! purpose
 
! purpose
 
|-
 
|-
| <tt>animals</tt>
+
| <samp>animals</samp>
| [[#Net fields|<tt>NetLongDictionary</tt>]] of <tt>FarmAnimal</tt>
+
| [[#Net fields|<samp>NetLongDictionary</samp>]] of <samp>FarmAnimal</samp>
 
| The farm animals currently in the location.
 
| The farm animals currently in the location.
 
|-
 
|-
| <tt>resourceClumps</tt>
+
| <samp>resourceClumps</samp>
| [[#Net fields|<tt>NetCollection</tt>]] of <tt>ResourceClump</tt>
+
| [[#Net fields|<samp>NetCollection</samp>]] of <samp>ResourceClump</samp>
 
| The giant crops, large stumps, boulders, and meteorites in the location.
 
| The giant crops, large stumps, boulders, and meteorites in the location.
 
|-
 
|-
| <tt>piecesOfHay</tt>
+
| <samp>piecesOfHay</samp>
| [[#Net fields|<tt>NetInt</tt>]]
+
| [[#Net fields|<samp>NetInt</samp>]]
 
| The amount of hay stored in silos.
 
| The amount of hay stored in silos.
 
|-
 
|-
| <tt>shippingBin</tt>
+
| <samp>shippingBin</samp>
| [[#Net fields|<tt>NetCollection</tt>]] of <tt>Item</tt>
+
| [[#Net fields|<samp>NetCollection</samp>]] of <samp>Item</samp>
 
| The items in the shipping bin.  
 
| The items in the shipping bin.  
 
|}</li>
 
|}</li>
   −
<li>There are a number of subclasses for specific location (like <tt>AdventureGuild</tt>) which have fields useful for specific cases.</li>
+
<li>There are a number of subclasses for specific location (like <samp>AdventureGuild</samp>) which have fields useful for specific cases.</li>
 
</ul>
 
</ul>
 
[[en:Modding:Modder_Guide/Game_Fundamentals]]
 
[[en:Modding:Modder_Guide/Game_Fundamentals]]
 
[[zh:模组:制作指南/游戏基本架构]]
 
[[zh:模组:制作指南/游戏基本架构]]

Навигация