模组:遷移至遊戲本體1.5.5

出自Stardew Valley Wiki
跳至導覽 跳至搜尋

目錄

Robin building.png
“我這裡還有很多事情需要處理。”
— 羅賓

不完整的翻譯

本文或部分尚未完全翻譯成中文。 歡迎您通過編輯幫助其建設。
最後編輯Shirotsuki於2023-04-04 18:20:11.

此頁面介紹了如何更新你的模組以與 Stardew Valley 1.5.5 兼容,並記錄了一些更改和新功能

對於 SMAPI MOD

星露谷兼容性分支

星露谷 1.5.5 可在每個作業系統的兩個分支中使用(遊戲內容完全相同):主分支 是默認安裝的選項,和一個可選的「兼容分支」適用於 早期的系統版本,它提供相同的內容,但使用不同的技術:

分支 系統 遊戲框架 運行時
主分支 Linux/macOS MonoGame 3.8 64 位 .NET 5
Windows MonoGame 3.8 64 位 .NET 5
兼容分支 Linux/macOS MonoGame 3.5.1 64 位 Mono 4.5
Windows XNA Framework 4.0 32 位 .NET Framework 4.5

但是 此版本的 SMAPI 僅支持遊戲的主分支 There are formidable difficulties across all mods in supporting all three variations Steam 用戶硬體數據 顯示大約 99.69% 的玩家擁有 64 位作業系統,而 32 位系統很多事情都不能做.

64 位 MonoGame 和 .NET 5

Stardew Valley 1.5.5 在所有平台上遷移到 64 位 MonoGame 和 .NET 5。SMAPI 可以自動重寫模組,所以它們應該仍然可以工作,但強烈建議為每個 C# mod 發布更新以避免特殊情況。

更新你的 C# 模組的代碼:

  1. 啟用 64 位 兼容性 如果你沒有準備好的話。(除非明確更改項目設置,否則默認情況下模組是 64 位的)
  2. 如果您還沒有將 .csproj 文件遷移到新格式:
    1. 更改模組工程的 .csproj 文件:
      <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
          <AssemblyName>程序集名称</AssemblyName>
          <RootNamespace>根命名空间</RootNamespace>
          <Version>版本</Version>
          <TargetFramework>net452</TargetFramework>
        </PropertyGroup>
      
        <ItemGroup>
          <PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="3.3.0" />
        </ItemGroup>
      </Project>
      
    2. 如果模組使用 Harmony,添加 <EnableHarmony>true</EnableHarmony> 到屬性組。
    3. 更新 程序集名稱根命名空間版本 標籤。(You can delete the AssemblyName and RootNamespace tags if they just match the project name.)
    4. 添加你要使用的任何 NuGet 包
    5. 刪除Properties/AssemblyInfo.cs文件, packages文件夾, 以及 packages.config 文件 (if present).
  3. Edit your mod's .csproj file, and replace <TargetFramework>net452</TargetFramework> with <TargetFramework>net5.0</TargetFramework>.
  4. Update the mod build package to the prerelease 3.4.0 version.
  5. Exit Visual Studio.
  6. Delete your solution's hidden .vs folder, and every project's bin and obj folders.
  7. Reopen the solution in Visual Studio, click Build > Rebuild Solution, fix any errors, and test the mod in-game.

Specific things to check for:

If you need help, feel free to ask in #making-mods on the Stardew Valley Discord!

Asset name format change

Some background first:

  • An asset name identifies an asset you can load through a content API like Game1.content.Load<T>("asset name"). For example: Characters/Abigail.
  • A file path identifies a physical file on the computer. For example: C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\Content\Characters\Abigail.xnb.

Stardew Valley 1.5.5 makes that distinction more important, since MonoGame uses Linux-style separators in asset names on all platforms. That means asset names no longer match path conventions on Windows.

You should review all code in your mods that creates/compares paths, check whether it's actually creating/comparing asset names, and if so migrate it to the equivalent methods:

code for file paths code for asset names
PathUtilities.NormalizePath("a/b") PathUtilities.NormalizeAssetName("a/b")
Path.Combine("a", "b") PathUtilities.NormalizeAssetName("a/b")
Path.DirectorySeparatorChar PathUtilities.AssetDirectorySeparator

Consistent game assembly name

Previously the game assembly was Stardew Valley on Windows, and StardewValley on Linux and macOS. The assembly is now named Stardew Valley on all platforms. Most mods shouldn't be affected once you update the mod build package.

Scarecrow changes

You can now patch Object.IsScarecrow() and/or Object.GetRadiusForScarecrow() (or add context tags) to support custom scarecrows or custom ranges.

Horse footstep changes

You can now override the footstep logic for a horse by setting its onFootstepAction field. For example:

Horse horse = ...; // get the horse instance you want to change
horse.onFootstepAction = (string tileType) =>
{
   // play custom audio, etc
};

Content changes

See For Content Patcher packs below, which applies for C# mods too.

For Content Patcher packs

Stardew Valley 1.5.5 has no known breaking changes for content packs. All content packs should work fine once the framework mod that loads them is updated.

Custom farm types

You can now add custom farm types by editing the Data/AdditionalFarms asset. Each entry consists of an object with these fields:

field description
ID A unique ID value. This must be globally unique across all mods, so you should prefix your mod ID (e.g., Example.PineapplesAnywhere/PineappleFarm). You should avoid commas for compatibility with Content Patcher packs checking the {{FarmType}} token. This is not shown in-game.
TooltipStringPath Where to get the translatable farm name and description. This must be a key in the form <asset name>:<key>; for example, Strings/UI:Farm_Description will get it from the Farm_Description entry in the Strings/UI file. The translated text must be in the form "<name>_<description>", like "Pineapple Farm_A farm shaped like a pineapple".
MapName The map asset name relative to the Maps folder. For example, Farm_Pineapple would load Maps/Farm_Pineapple.
IconTexture (optional) The asset name for a 22x20 pixel icon texture, shown on the 'New Game' and co-op join screens.
WorldMapTexture (optional) The asset name for a 131x61 pixel texture that's drawn over the farm area in the in-game world map.
ModData (optional) A string→string dictionary of mod-specific metadata for the farm, which can be accessed in C# code via Game1.GetFarmTypeModData(key).

For example, this Content Patcher pack would create a 'pineapple' farm:

{
    "Format": "2.0.0",
    "Changes": [
        // add farm type
        {
            "Action": "EditData",
            "Target": "Data/AdditionalFarms",
            "Entries": {
                "Pathoschild.PineappleFarm/PineappleFarm": { // for technical reasons, you need to specify the ID here *and* in the "ID" field
                    "ID": "Pathoschild.PineappleFarm/PineappleFarm",
                    "TooltipStringPath": "Strings/UI:Pathoschild_PineappleFarm",
                    "MapName": "Pathoschild_PineappleFarm",
                    "IconTexture": "Mods/Pathoschild.PineappleFarm/Icon",
                    "WorldMapTexture": "Mods/Pathoschild.PineappleFarm/WorldMap"
                }
            }
        },

        // add farm name + description
        {
            "Action": "EditData",
            "Target": "Strings/UI",
            "Entries": {
                "Pathoschild_PineappleFarm": "Pineapple Farm_A farm shaped like a pineapple!" // tip: use {{i18n}} to translate it
            }
        },

        // load map
        {
            "Action": "Load",
            "Target": "Maps/Pathoschild_PineappleFarm",
            "FromFile": "assets/map.tmx"
        },

        // load icon
        {
            "Action": "Load",
            "Target": "Mods/Pathoschild.PineappleFarm/Icon, Mods/Pathoschild.PineappleFarm/WorldMap",
            "FromFile": "assets/{{TargetWithoutPath}}.png"
        }
    ]
}

Custom languages

You can now add custom languages by editing the Data/AdditionalLanguages asset. Each entry consists of an object with these fields:

field description
ID A unique ID value. This is not shown in-game.
LanguageCode The language code for this localization. This should ideally be a ISO 639-1 code. You should avoid commas for compatibility with Content Patcher packs checking the {{Language}} token.
ButtonTexture The asset name for a 174x78 pixel texture containing the button of the language for language selection menu. The top half of the sprite is the default state, while the bottom half is the hover state.
UseLatinFont Whether the language uses the same Latin character font as English. If set to false, you must set the next field.
FontFile (optional) The asset name for the font file to use (if UseLatinFont is false).
FontPixelZoom (optional) A factor by while to multiply the font size.
FontApplyYOffset (optional) Whether to shift the font up by four pixels (multiplied by the FontPixelZoom), to better align languages with larger characters like Chinese and Japanese.
SmallFontLineSpacing (optional) The line spacing value used by smallFont. Defaults to 26.
TimeFormat A string which describes the in-game time format, with tokens replaced by in-game values. For example, [HOURS_12]:[MINUTES] [AM_PM] would show 12:00 PM at noon.

The valid tokens are:

  • [HOURS_12]: hours in 12-hour format, where midnight and noon are both "12".
  • [HOURS_12_0]: hours in 12-hour format, where midnight and noon are both "0".
  • [HOURS_24]: hours in 24-hour format, where midnight is "0" and noon is "12".
  • [HOURS_24_00]: hours in 24-hour format with zero-padding, where midnight is "00" and noon is "12".
  • [MINUTES]: minutes with zero-padding.
  • [AM_PM]: the localized text for "am" or "pm" (taken from Strings\\StringsFromCSFiles:DayTimeMoneyBox.cs.10370 and DayTimeMoneyBox.cs.10371 respectively). The game shows "pm" between noon and 11:59pm inclusively; it shows "am" otherwise.
ClockTimeFormat A string which describes the in-game time format. Equivalent to TimeFormat, but used for the in-game clock.
ClockDateFormat A string which describes the in-game date format as shown in the in-game clock, with tokens replaced by in-game values. For example, [DAY_OF_WEEK]. [DAY_OF_MONTH] would show Mon. 1.

The valid tokens are:

  • [DAY_OF_WEEK]: the abbreviated day of week as returned by Game1.shortDayDisplayNameFromDayOfSeason (like Mon for Monday).
  • [DAY_OF_MONTH]: the numerical day of the month.

For example, this Content Patcher pack would add Esperanto to the game:

{
    "Format": "2.0.0",
    "Changes": [
        // define language
        {
            "Action": "EditData",
            "Target": "Data/AdditionalLanguages",
            "Entries": {
                "Pathoschild.Esperanto": { // for technical reasons, you need to specify the ID here *and* in the "ID" field
                    "ID": "Pathoschild.Esperanto",
                    "LanguageCode": "eo",
                    "ButtonTexture": "Mods/Pathoschild.Esperanto/Button",
                    "UseLatinFont": true,
                    "TimeFormat": "[HOURS_24_00]:[MINUTES]",
                    "ClockTimeFormat": "[HOURS_24_00]:[MINUTES]",
                    "ClockDateFormat": "[DAY_OF_WEEK] [DAY_OF_MONTH]"
                }
            }
        },

        // load button texture
        {
            "Action": "Load",
            "Target": "Mods/Pathoschild.Esperanto/Button",
            "FromFile": "assets/button.png"
        }
    ]
}

Once the language is defined, you can add translations to the game by patching game assets like usual, and use the language code you specified above. For example:

{
    "Action": "EditData",
    "Target": "Strings/StringsFromCSFiles",
    "Entries": {
        "Game1.cs.3043": "Lundo",
        "Game1.cs.3044": "Mardo",
        ...
    },
    "When": {
        "Language": "eo"
    }
}

Custom festival location names

The location name in the festival-started message (e.g., "The Luau has begun on the beach") was previously hardcoded, so it would always show the internal name for non-vanilla festival locations. You can now add a locationDisplayName field in the Data/Festivals/* file to set the display name.

Custom spouse rooms

Adding spouse rooms for custom NPCs is now much easier. You can edit the Data/SpouseRooms asset to add the spouse room info in this format: "<NPC name>": "<map name>/<map index>".

field effect
<NPC name> The internal name of the NPC (i.e., their key in Data/NPCDispositions).
<map name> The asset name of the map in the game's Content/Maps folder. This can be a custom map loaded through Content Patcher's Load action or SMAPI's IAssetLoader API.
<map index> The index of the spouse room within the map file, to allow multiple spouse rooms in the same file. Each spouse room is 6 tiles across by 9 tiles down, starting with index 0 in the top-left corner. You can have any number of rows and columns (the index will wrap at the end of the row), as long as they fit an integer number of spouse rooms.

Map property changes

Stardew Valley 1.5.5 adds several map properties:

valid in map property usage
farm FarmFishLocationOverride <location name> <chance> Adds an alternative location name when catching fish, where the <chance> is a decimal value between 0 (never happens) and 1 (always happens). For example, FarmFishLocationOverride Mountain 0.5 adds a 50% chance of catching mountain fish instead of the normal fish for that location. The location name is case-sensitive, and matches those shown by the Debug Mode mod.
farm FarmHouseFurniture [<furniture ID> <tile X> <tile Y> <rotations>]+ Spawns initial furniture in the farmhouse when creating a new save. If you add multiple furniture to the same tile, the first one will be placed on the ground and the last one will be placed on the first one.
This is also required to enable the FarmHouseWallpaper, FarmHouseFlooring, and FarmHouseStarterSeedsPosition properties. You can enable it without spawning any furniture with FarmHouseFurniture -1 0 0 0.
farm FarmHouseFlooring <flooring id> Sets the initial farmhouse floor to the given ID when creating a new save. These are mapped to the 4x4 tile areas in the Maps/walls_and_floors tilesheet starting at tile index 336 (where index 0 is mapped to the top-left square).
This is only enabled if FarmHouseFurniture is set.
farm FarmHouseWallpaper <wallpaper id> Sets the initial farmhouse wallpaper to the given ID when creating a new save. These are mapped to the 1x4 tile areas in the Maps/walls_and_floors tilesheet starting from the top-left.
This is only enabled if FarmHouseFurniture is set.
farm FarmHouseStarterSeedsPosition <tile X> <tile Y> Sets the tile position in the farmhouse where the seed package is placed when creating a new save.
This is only enabled if FarmHouseFurniture is set.
farm FarmOceanCrabPotOverride T Whether crab pots on the farm should catch ocean fish.
any ForceAllowTreePlanting T Whether to allow planting trees (both wild and fruit) in this location, even if it normally wouldn't be allowed.
any IsFarm T Whether to mark the location as a farm. This only affects generic location/interaction logic which checks the in-code location.IsFarm property; logic hardcoded into the game's Farm class (e.g., farm animals, pets, crows/scarecrows, greenhouse, farm buildings, etc) is still limited to the actual farm.
any IsGreenhouse T Whether to mark the location as a greenhouse.
farm SpawnBeachFarmForage T Whether to randomly spawn beach forage and 補給箱 on the farm (like the vanilla beach farm). Forage and crates will only appear on tiles which have the BeachSpawn T property on the Back layer, are clear for placement, and don't have a tile on the AlwaysFront layer.
farm SpawnForestFarmForage T Whether to randomly spawn forest forage on the farm (like the vanilla forest farm). Forage will only spawn on tiles which have the Type Grass tile property, are clear for placement, and don't have a tile on the AlwaysFront layer.
farm SpawnMountainFarmOreRect <tile X> <tile Y> <tile width> <tile height> The tile area on the farm map where ores should randomly spawn (like the vanilla hilltop farm). Ores will only spawn on tiles which have the Type Dirt tile property and are clear for object placement.

And one new tile property:

layer property effect
Back TouchAction Warp <area> <x> <y> [string prerequisite] Adds a player-only warp on the tile to the specified location name and position. This is exactly equivalent to TouchAction MagicWarp, but without the magic sound/visual effect.

It also changes one tile property:

layer property effect
Back Water Setting the value to I (uppercase i) will make the tile behave like normal water, but won't render the water animation overlay for it.

Non-Krobus roommates

The game's 婚姻 logic previously had hardcoded exceptions to treat 科羅布斯 as a roommate instead. That logic has been reworked so it can be applied to any NPC (including custom NPCs).

Specifically:

  • Items with the "propose_roommate_<NPC name>" context tag will trigger a roommate proposal when given to the named NPC. The NPC name must be lowercase with underscores instead of spaces (e.g., propose_roommate_dwarf).
  • These dialogue keys apply before they move in:
    content file key effect
    Strings/StringsFromCSFiles <NPC name>_EngagedRoommate The NPC's roommate proposal accept dialogue.
    ⚠ Ignored if you don't specify Data/EngagementDialogue:<NPC name>Roommate0.
    For example: A Void Ghost pendant! How did you...?$3#$b#Oh, wow.$7#$b#@... yes, I'll come live with you, if you like. But we have to keep it secret from everyone.#$b#I'll be at your house in a few days... okay?$h
    Strings/Characters MovieInvite_NoTheater The NPC's roommate proposal rejection text when you don't meet the requirements (i.e., min friendship + house upgrade level, and not already having a roommate/spouse). This is the same dialogue used when you can't invite someone to the movies.
    Data/EngagementDialogue <NPC name>Roommate0
    <NPC name>Roommate1
    The NPC's normal dialogue after accepting the proposal, but before moving in. The Roommate0 variant is always used on the day the NPC accepted; on subsequent days the NPC randomly chooses Roommate0 or Roommate1. If the Roommate0 variant isn't defined, the NPC will use the normal <NPC Name>0 and <NPC Name>1 keys. If the Roommate0 variant is defined, Roommate1 must be set too to avoid errors.
    For example: @... I'm afraid we'll have to keep this a secret... Neither my people nor yours would accept us living together.

    And after they move in:

    content file key effect
    Characters/Dialogue/MarriageDialogue<NPC name>Roommate all keys Equivalent to Characters/Dialogue/MarriageDialogue<NPC name>, but only applies if the NPC is a roommate. If the file exists, it completely replaces the spouse version; otherwise the game defaults to the spouse version.
    Characters/Dialogue/MarriageDialogue *Roommate Keys with the Roommate suffix take priority if they exist (only in this file, not the MarriageDialogue<NPC name> files).
    Data/Festivals/* <NPC name>_roommate The NPC's normal dialogue at the festival if they're a roommate. If the key isn't defined, they'll use <NPC name>_spouse instead.

    And for other NPCs:

    content file key effect
    Characters/Dialogue/* *_roommate_* Equivalent to the *_inlaw_* infix in generic dialogue, used if you're a roommate with the NPC. If not defined, the game will fallback to the non-infixed dialogue (it won't use the *_inlaw_* variant).
  • Roommates will sleep in a 單人床 if one is available and unused in the house; otherwise they'll use a double bed like a normal spouse. (Krobus is an exception, since he doesn't sleep in a bed.)
  • Added event preconditions to check whether the local player has a roommate (R) or doesn't have a roommate (Rf). This can be combined with O <NPC name> to check for a specific roommate, like R/O Abigail.

Custom scarecrows

You can now mark any placeable item as a 稻草人 with two new context tags:

context tag effect
crow_scare Sets the item as a placeable scarecrow. If not set, the item is considered a scarecrow if its default name contains the substring arecrow (like before).
crow_scare_radius_<radius> If the item is a scarecrow, sets the radius that it covers. If not set, the scarecrow defaults to 17 if the default name contains the substring Deluxe and 9 otherwise.

Update impact

Stardew Valley 1.5.5 only has technical changes; there are no known changes to the player-visible content. Known changes:

content file changes
Effects/BloomCombine
Effects/BloomExtract
Effects/GaussianBlur
These files were deleted.
Fonts/* The actual font files are unchanged, but the JSON output for some fonts when unpacked by StardewXnbHack is a bit different due to the XNA Framework → MonoGame change.

See also