User:Pathoschild/Modding wishlist

From Stardew Valley Wiki
Jump to: navigation, search

A list of requested changes in the game code to support modders. This list does not include complex refactoring or rewriting, which is unlikely to be accepted.

Wishlist

Bug fixes

All done!

Small changes

  • ☐ Tweak accessibility modifiers:
    class changes
    SDKs/GalaxyNetClient
    • make field protected: client.
  • ☐ Change NPC.CanSocialize to a { get; set; } property, and set it in the constructor instead. (That will let mods change the value without subclassing NPC.)
  • ☐ Remove unused code:
    • BloomComponent, BloomSettings, and all code which references them (this is broken and never enabled).
    • TerrainFeatures/DiggableWall (unused).
    • TerrainFeatures/TerrainFeatureFactory (unused).
  • ☐ Remove unused content files:
    • Characters/schedules/beforePathfinding/*
    • Characters/schedules/newSchedules/*
    • Characters/schedules/spring/*

Medium changes

All done!

Refactoring

  • ☐ Change all const fields to static readonly. They're accessed the same way and the performance difference is negligible, but that'll make the decompiled code much easier to understand, and avoid issues where const values get 'baked in' to mod assemblies.
  • ☐ Some XNB files have a separate display name field, but only in non-English. Using display names consistently regardless of language would let mods rename things without breaking keys.

Done in Stardew Valley 1.3.27

Bug fixes

  • ☑ Fix strange null handling with net fields (mostly fixed).
  • ☑ Fix bee houses hardcoded to check Farm location, instead of their current location.
  • ☑ On the load menu, clicking the 'back' button clicks the slot under it.
  • Object.getOne() doesn't copy the 1.2+ fields: name, DisplayName, preserve, preservedParentSheetIndex, and honeyType.

Small changes

  • ☑ Include Stardew Valley.pdb in the release, so we get line numbers when a crash happens in game code.
  • ☑ Add a SerializableDictionary<string, string> CustomData property to SaveData, for SMAPI mods to safely store data.
  • ☑ Remove Farmer namespace (so we don't need to alias the Farmer class anymore).
  • ☑ Make these Game1 fields protected instead of private: _debugStringBuilder, _fpsList, _fpsStopwatch, _fps, _newDayTask, _bgColor, screen, lightingBlend, drawFarmBuildings, drawHUD, drawDialogueBox, drawOverlays, and renderScreenBuffer. That will let SMAPI override the draw loop without reflection calls.
  • ☑ Make LocalizedContentManager.languageCodeString public. That will let SMAPI override the draw loop without reflection calls.
  • ☑ Remove LocalizedContentManager.LanguageOverride; it's unused, and that way SMAPI won't need to handle it.
  • ☑ Replace ChatBox.enableCheats() with a property.
  • ☑ Make these methods/properties virtual:
    • Item:
      • canStackWith
      • CompareTo
    • ☑ LocalizedContentManager:
      • CreateTemporary
      • Load(assetName, language)
      • LoadBase
      • CreateTemporary
      • LoadString
      • LoadBaseString
    • Buildings/Building:
      • textureName
      • resetTexture
      • showUpgradeAnimation
      • getNameOfNextUpgrade
      • showDestroyedAnimation
      • updateInteriorWarps
      • drawInConstruction
    • Buildings/Stable:
      • grabHorse
    • Locations/FarmHouse:
      • showSpouseRoom
      • loadMapForUpgradeLevel
      • setMapForUpgradeLevel
      • loadSpouseRoom
    • Menus/ChatBox:
      • textboxEnter
      • runCommand (and mark it protected)
      • addInfoMessage
      • globalInfoMessage
      • addErrorMessage
      • listPlayers
      • showHelp
      • setText
      • messageColor (and mark it protected)
      • receiveChatMessage
      • addMessage
    • Menus/IClickableMenu:
      • receiveRightClick (currently abstract)
    • Network/NetAudioCueManager:
      • Update
    • Objects/Chest:
      • grabItemFromChest
      • addItem
      • grabItemFromInventory
      • isEmpty
      • clearNulls
      • draw (last overload)
    • Objects/Object:
      • cutWeed
      • isAnimalProduct
      • canBeShipped
      • rot
      • isForage
      • initializeLightSource
      • consumeRecipe
      • performUseAction
      • grabItemFromAutoGrabber
      • farmerAdjacentAction
      • addWorkingAnimation
      • drawAsProp
      • sellToStorePrice
    • Projectiles/Projectile:
      • update
    • TV
  • Make Farmer.friendships internal to avoid confusion (replaced with friendshipData) (not possible due to XML serialisation requirements).
  • Include Stardew Valley.xml in the release (if available), so we get code documentation (no code documentation available).

Medium changes

  • ☑ Add Game1.hooks to let SMAPI intercept some core game logic.
  • ☑ Add Game1.input, which centralises Keyboard.GetState(), Mouse.GetState(), and GamePad.GetState().
  • ☑ Add a GameLocation.IsGreenhouse property, set it to true for the greenhouse, and use it anywhere the game checks .Name.Equals("Greenhouse"). That will let mods add custom indoor locations where crops can grow.
  • ☑ Change GameLocation.updateSeasonalTilesheets to enable custom seasonal tilesheets.
  • ☑ Instead of hardcoding non-social NPCs in new SocialMenu(...), add a virtual npc.CanSocialise field.
  • ☑ Integrate SMAPI's SDate features into the new WorldDate (like comparison operators and DayOfWeek).
  • ☑ Add events to NetList for item added/removed/replaced (similar to the ones NetDictionary has). SMAPI will use them to watch for changes in some collections (like player inventory).

Refactoring

  • ☑ Change static Multiplayer class into a Game1.multiplayer field so SMAPI can override it, and make its methods non-static and virtual.
  • ☑ Use interfaces instead of concrete types to let SMAPI/mods override them:
    • Farmer:
      • IList<Buff> buffs
      • IList<OutgoingMessage> messageQueue
    • Game1:
      • NetBase<IWorldState> netWorldState (create interface)
      • IGameServer GameServer (create interface)
      • ISoundBank soundBank (create interface with thin wrapper around SoundBank)
      • IList<GameLocation> locations
      • IList<Item> itemsToShip
      • IList<IClickableMenu> onScreenMenus
      • IList<DelayedAction> delayedActions
      • IDictionary<int, string> objectInformation
      • IDictionary<int, string> bigCraftablesInformation
      • IDictionary<string, string> NPCGiftTastes
  • Use Game1.CreateContentManager consistently.
  • ☑ Internal changes to CoopMenu so SMAPI can hook into it.
  • ☑ Replace obj.getType() == type with obj is type to support mod subclasses in various places.
  • Update the bundled Mono to the latest version (declined, too big a change).
  • Include a full (non-stripped) bundled Mono, to avoid issues with mod code (declined, too big a change).

Done in Stardew Valley 1.3.28

Small changes

  • ☑ When creating honey, set preservedParentSheetIndex to the flower's item ID.
  • ☑ Make LoadGameMenu's inner classes public.
  • ☑ Change ItemGrabMenu.sourceItem to public readonly object context, and track non-objects too. Suggested values:
    • Chest instance when opening a chest (like current sourceItem);
    • auto-grabber / Mill / JunimoHut instance when viewing their output;
    • AdventureGuild / LibraryMuseum / JunimoNoteMenu / FishingRod instance for their rewards;
    • Farm.shippingBin for the shipping bin;
    • Item instance if opened by a method like addItemByMenuIfNecessary;
    • null if not applicable.
  • ☑ Change GameLocation.IsGreenhouse to a { get; set; } property, and set it in the location constructor instead.
  • ☑ When logging an exception, use Console.WriteLine(exception.ToString()) instead of Console.WriteLine(exception.GetType()) + Console.WriteLine(exception.Message) + Console.WriteLine(exception.StackTrace). This will let SMAPI detect exception messages more easily.
  • ☑ Make these methods virtual:
    • Character:
      • checkForFootstep
    • Locations\DecoratableLocation:
      • isTileOnWall
      • setFloors
      • setWallpapers
      • getFloorAt
      • getWallForRoomAt
      • setFloor
      • getWalls (and make it non-static)
      • getFloors (and make it non-static)

Done in Stardew Valley 1.3.32

Small changes

  • ☑ Tweak accessibility modifiers:
    class changes
    Multiplayer
    • Make field protected: disconnectingFarmers.
    Network/NetBufferReadStream,
    Network/NetBufferWriteStream
    • Make classes public.
    Network/LidgrenServer
    • Make fields protected: peers and server.
    • Make methods protected virtual: sendMessage(NetConnection, OutgoingMessage) and parseDataMessageFromClient.
    SDKs/GalaxyNetClient
    • make fields protected: client.
    • make methods protected virtual: onReceiveConnection, onReceiveMessage, onReceiveDisconnect, and onReceiveError.
    SDKs/GalaxyNetServer
    • make class public.
    • make fields protected: server and peers.
    • make methods protected virtual: onReceiveConnection, onReceiveMessage, onReceiveDisconnect, onReceiveError, and sendMessage(GalaxyID, OutgoingMessage).
  • ☑ Changes to use IsGreenhouse:
    location changes
    Crop.newDay
    // from:
    if (... || !this.seasonsToGrowIn.Contains(Game1.currentSeason) || ...)
    
    // to: 
    if (... || (!environment.IsGreenhouse && !this.seasonsToGrowIn.Contains(Game1.currentSeason)) || ...)
    
    HoeDirt.canPlantThisSeedHere
    // from:
    if (!Game1.currentLocation.IsOutdoors || crop.seasonsToGrowIn.Contains(Game1.currentSeason))
    
    // to:
    if (!Game1.currentLocation.IsOutdoors || Game1.currentLocation.IsGreenhouse || crop.seasonsToGrowIn.Contains(Game1.currentSeason))
    
    HoeDirt.plant
    // from:
    if (!who.currentLocation.isFarm && who.currentLocation.IsOutdoors)
    
    // to: 
    if (!who.currentLocation.isFarm && !who.currentLocation.IsGreenhouse && who.currentLocation.IsOutdoors)
    
    // from:
    if (!who.currentLocation.isOutdoors || crop.seasonsToGrowIn.Contains(Game1.currentSeason))
    
    // to:
    if (!who.currentLocation.isOutdoors || who.currentLocation.IsGreenhouse || crop.seasonsToGrowIn.Contains(Game1.currentSeason))