About this mod
Implements simple, extensible water and power grids in Stardew Valley.
- Requirements
- Permissions and credits
- Changelogs
- Donations
- Adds individual water and power grid overlays to any and all locations that can be toggled on and off with a hotkey
- Recognizes objects that need or produce water and / or power using Content Patcher packs
- Prevents recognized vanilla and custom objects from working if they have insufficient power or water
- Allows pipes to cost money and / or items to build, return money and / or items when destroyed
- Shows object input / output on the overlay
- Uses colors to differentiate grid types, powered / unpowered grids, and powered / unpowered objects
- Variables are customizable using Generic Mod Config Menu or editing config.json
- Colors are customizable by editing config.json
- Strings are translatable using i18n system
- Includes a mod API for integrating other mods
Basic Usage
Manipulate the grid using the following customizable hotkeys while on the farm:
- [Home] - Toggle showing grid overlay
- [Delete] - Switch between water and electric grids
- [End] - Toggle pipe editing
- [PageUp] - Cycle through pipe section to be placed type (end point, straight, elbow, T joint, and four-way joint)
- [PageDown] - Rotate pipe section to be placed 90 degrees
- [LeftMouse] - Place current pipe section on the selected tile
- [RightMouse] - Destroy pipe section on the selected tile
You cannot place or destroy tiles while carrying an object above your head.
By default, pipes cost 100 pieces of money and 2 copper ore to build, and return 50 pieces of money and 1 copper ore when destroyed.
Replacing a pipe with another pipe is considered both destroying the old and building the new.
Pipe costs and returns can be changed in the config.
Colors
Colors can be changed by editing the mod's config.json file. In the file, colors are Blue, Green, Red, Alpha objects, each 0 - 255.
- Unpowered grids are white.
- Powered electricity grids are yellow.
- Powered water grids are aqua.
- Object that are receiving sufficient power will show their power number in the grid color
- Objects that are not receiving sufficient power will show their power number in red.
Utility Grid Mods
You can install any of the following mods to make use of your new utility grids:
- Pipe Irrigation - lets you water crops using just an underground water pipe system.
- Simple Irrigation System - adds four water pumps, and causes the various sprinkler types to require water and power to work.
- Simple Electricity System - makes electrical stations require electricity, makes furnaces, charcoal kilns, and solar panels produce electricity, lets the charcoal kiln consume coal
- Strange Machines Utility Grid - for Strange Machines mod.
- Utility Grid Storage - adds a water tank and two battery stations for power storage.
Let me know if you make a mod to add to this list.
Utility Objects
Any object placed on a farm tile can be a utility object. To make the mod recognize an object as a utility object, use a Content Patcher patch, with the following syntax (for example):
{
"Format": "1.23.0",
"Changes": [
{
"Action": "EditData",
"Target": "utility_grid_object_dictionary",
"Entries": {
"Water Pump": {
"water": 10,
"electric": -2,
"onlyInWater": true
},
"Furnace": {
"electric": 10,
"mustBeOn": true,
"mustBeWorking": true,
"mustBeFull": true
},
"Crystalarium": {
"electric": -3,
"mustBeWorking": true,
"mustBeFull": true
},
"Iridium Sprinkler": {
"water": -6,
"electric": -2
}
}
}
]
}
utility_grid_object_dictionary is the path the mod uses to collect all entries passed by Content Patch mods.
Each entry key in the dictionary should be the name of the object to be recognized (may be different from the object's display name).
Each entry value in the dictionary is an object that can have the following keys:
- "water" - a positive or negative decimal of how much water this object provides or uses.
- "electric" - a positive or negative decimal of how much electricity this object provides or uses.
- "mustBeOn" - true or false, whether the object must be in its on state in order to provide power (IsOn == true)
- "mustBeWorking" - true or false, whether the object must be processing in order to provide power (minutesUntilReady > 0)
- "mustBeFull" - true or false, whether the object must have a pending product in order to provide power (heldObject.Value != null)
- "mustContain" - string name of an game item, whether the object must have that specific item as a product in order to provide power (heldObject.Value == obj.mustContain)
- "mustHaveSun" - true or false, whether the object must have sun to produce power
- "mustHaveRain" - true or false, whether the object must have rain to produce power
- "mustHaveLightning" - true or false, whether the object must have lightning to produce power
- "onlyInWater" - true or false, whether the object can only be placed in water (special for water pumps)
- onlyDay - true or false, whether the object should only work during daylight hours
- onlyNight - true or false, whether the object should only work during night hours
- onlyMorning - true or false, whether the object should only work at the beginning of the day
- "electricChargeCapacity" - positive integer, how much electricity this object can hold (for storage objects)
- "electricChargeRate" - positive integer, how much electricity this object can gain per hour (for storage objects)
- "electricDischargeRate" - positive integer, how much electricity this object can provide per hour (for storage objects)
- "waterChargeCapacity" - positive integer, how much water this object can hold (for storage objects)
- "waterChargeRate" - positive integer, how much water this object can gain per hour (for storage objects)
- "waterDischargeRate" - positive integer, how much water this object can provide per hour (for storage objects)
An alternative means of labeling an object for recognition is to add a key to the Object.modData field "aedenthorn.UtilityGrid/water" and/or "aedenthorn.UtilityGrid/electric", along with any other field you wish to set, and the mod will recognize it and add it to the dictionary.
Mod API
Mods can call this mod's API to do the following:
- add a function to change the power of a pipe group - arguments passed to the function are the location name, the type of grid (0 = water, 1 = electric), and a list of the pipe tiles. The function should return a Vector2, with X as a positive production value and/or Y as a negative requirement value.
- add an event handler to fire when the grid is shown, hidden, or changed
- get whether an object is powered
- get whether an object is working (i.e. fulfills the production conditions specified for that type of object)
- get a list of connected utility object lists for a grid type in a location
- get a list of connected pipe tile groups for a grid type in a location
- get the electric and water production / usage of an object at a tile
- refresh either grid immediately
- manually set the electricity or water value for a grid object
- check whether a water or electricity grid is showing
- get a list of utility objects connected to a specific tile in a location
- get the electric or water power of a tile's pipe group (x is positive total input and y is negative total requirement)
- get a list of water or electricity tiles connected to a tile
The current interface is:
public interface IUtilityGridApi
{
public void AddPowerFunction(Func<string, int, List<Vector2>, Vector2> function);
public void AddHideGridAction(EventHandler<KeyValuePair<GameLocation, int>> handler);
public void AddRefreshAction(EventHandler<KeyValuePair<GameLocation, int>> handler);
public void AddShowGridAction(EventHandler<KeyValuePair<GameLocation, int>> handler);
public bool IsObjectPowered(GameLocation location, int x, int y);
public bool IsObjectWorking(GameLocation location, int x, int y);
public List<List<Vector2>> LocationElectricObjects(GameLocation location);
public List<List<Vector2>> LocationElectricPipes(GameLocation location);
public List<List<Vector2>> LocationWaterObjects(GameLocation location);
public List<List<Vector2>> LocationWaterPipes(GameLocation location);
public Vector2 ObjectWaterElectricityVector(GameLocation location, int x, int y);
public bool SetObjectWater(GameLocation location, int x, int y, int amount);
public void RefreshElectricGrid(GameLocation location);
public void RefreshWaterGrid(GameLocation location);
public bool SetObjectElectricity(GameLocation location, int x, int y, int amount);
public bool ShowingElectrictyGrid();
public bool ShowingWaterGrid();
public List<Vector2> TileGroupElectricityObjects(GameLocation location, int x, int y);
public Vector2 TileGroupElectricityVector(GameLocation location, int x, int y);
public List<Vector2> TileGroupWaterObjects(GameLocation location, int x, int y);
public Vector2 TileGroupWaterVector(GameLocation location, int x, int y);
public List<Vector2> TileElectricGrid(GameLocation location, int x, int y);
public List<Vector2> TileWaterGrid(GameLocation location, int x, int y);
}
Technical
Requires SDV 1.5.5+
Requires SMAPI, uses Harmony.
Compatible with Mod Updater for automatic updates.
Code is at https://github.com/aedenthorn/StardewValleyMods.
If you want to complain or ask for help or help me test my mods, you can visit my Discord server.
A list of all my mods for Stardew Valley is available at https://www.nexusmods.com/stardewvalley/articles/895.