Difference between revisions of "Modding:Modder Guide/APIs/Utilities"
Pathoschild (talk | contribs) (→Mod path: expand) |
Pathoschild (talk | contribs) (→Mod path: use 'this.Helper' form so it works outside Entry method) |
||
Line 11: | Line 11: | ||
You don't need to worry about that when using SMAPI APIs, which take relative paths and automatically fix the path format if needed: | You don't need to worry about that when using SMAPI APIs, which take relative paths and automatically fix the path format if needed: | ||
<source lang="c#"> | <source lang="c#"> | ||
− | var data = | + | var data = this.Helper.Data.ReadJsonFile<SomeDataModel>("assets/data.json"); |
</source> | </source> | ||
Revision as of 15:50, 30 September 2020
- Get started
- Game fundamentals
- Test & troubleshoot
- Release
- API reference
- Basic SMAPI APIs:
- Advanced SMAPI APIs:
- Specific guides
SMAPI provides some C# objects you can use to simplify your code.
Metadata
Mod path
Before handling mod folder paths, be aware that:
- The mod's folder path is not consistent. The game is installed to different paths, Nexus mods are often unzipped into a folder like Mods/Your Mod Name 1.27.5-541-1-27-5-1598664794/YourModFolder by default, and players can organize their mod folders like Mods/For single-player/YourModFolder.
- Paths are formatted differently on Linux/Mac/Android vs Windows.
You don't need to worry about that when using SMAPI APIs, which take relative paths and automatically fix the path format if needed:
var data = this.Helper.Data.ReadJsonFile<SomeDataModel>("assets/data.json");
If you really need a full path, you should use this.Helper.DirectoryPath and Path.Combine to get it:
string path = Path.Combine(this.Helper.DirectoryPath, "assets", "data.json"); // "assets/data.json" in the current mod's folder
var file = new FileInfo(path);
See Constants for other paths like the game folder.
Constants
The Constants class provides metadata about SMAPI and the game.
value | meaning |
---|---|
Constants.ApiVersion | The version of the running SMAPI instance. |
Constants.MinimumGameVersion Constants.MaximumGameVersion |
The game versions supported by the running SMAPI instance. |
Constants.TargetPlatform | The current operating system (one of Android, Linux, Mac, or Windows). |
Constants.ExecutionPath | The absolute path to the Stardew Valley folder. |
Constants.DataPath | The absolute path to the game's data folder (which contains the save folder). |
Constants.LogDir | The absolute path to the folder containing the game and SMAPI logs. |
Constants.SavesPath | The absolute path to the save folder. |
Constants.CurrentSavePath | The absolute path to the current save folder, if a save is loaded. |
Constants.SaveFolderName | The name of the current save folder (like Name_012345789), if a save is loaded. |
Context
The Context class provides information about the game state and player control:
value | meaning |
---|---|
Context.IsGameLaunched | Whether the game has been launched and initialised. This becomes true immediately before the first update tick. |
Context.IsWorldReady | Whether the player has loaded a save and the world has finished initialising. Useful for ignoring events before the save is loaded. |
Context.IsPlayerFree | Whether Context.IsWorldReady and the player is free to act on the world (no menu is displayed, no cutscene is in progress, etc). |
Context.CanPlayerMove | Whether Context.IsPlayerFree and the player is free to move (e.g. not using a tool). |
Context.IsMultiplayer | Whether Context.IsWorldReady, and the player loaded the save in multiplayer mode (regardless of whether any other players are connected). |
Context.IsMainPlayer | Whether Context.IsWorldReady, and the player is the main player. This is always true in single-player, and true when hosting in multiplayer. |
Helpers
Dates
Use SDate for calculating in-game dates. You start by creating a date:
var date = SDate.Now(); // current date
var date = new SDate(28, "spring"); // date in the current year
var date = new SDate(28, "spring", 2); // date in the given year
var date = SDate.From(Game1.Date); // from a game date
Then you can calculate offsets from any date:
// add days
new SDate(28, "spring", 1).AddDays(370); // 06 fall in year 4
// subtract days
new SDate(01, "spring", 2).AddDays(-1); // 28 winter in year 1
...and compare dates:
var a = new SDate(01, "spring");
var b = new SDate(02, "spring");
if (a < b) // true
...
...and get a translated date string:
var date = new SDate(15, "summer");
string message = $"See you on {date.ToLocaleString(withYear: false)}!"; // See you on Summer 15!
Note that SDate won't let you create invalid dates:
// ArgumentException: Invalid day '30', must be a value from 1 to 28.
new SDate(30, "spring");
// ArithmeticException: Adding -1 days to 01 spring Y1 would result in invalid date 28 winter Y0.
new SDate(01, "spring", 1).AddDays(-1);
Once created, dates have a few properties you can use:
property | meaning |
---|---|
Day | The day of month. |
Season | The normalised season name. |
SeasonIndex | The zero-based season index recognised by game methods like Utility.getSeasonNameFromNumber. |
Year | The year number. |
DayOfWeek | The day of week (like Monday). |
DaysSinceStart | The number of days since the first day, inclusively (i.e. 01 spring Y1 = 1). |
File paths
PathUtilities provides utility methods for working with file paths and asset names, complementing the Path class provided by .NET:
method | usage |
---|---|
GetSegments
|
Split a path into its delimited segments, like /usr/bin/example → usr , bin , and example . For example:
string[] segments = PathUtilities.GetSegments(Constants.ExecutionPath);
|
IsSafeRelativePath
|
Get whether a path is relative and doesn't contain directory climbing (../ ), so it's guaranteed to be within the parent folder.
|
IsSlug
|
Get whether a string can be used as a 'slug', containing only basic characters that are safe in all contexts (e.g. filenames, URLs, SMAPI IDs, etc). |
NormalizePath
|
Normalize file paths or asset names to match the format used by the current OS. For example:
string path = PathUtilities.NormalizePathSeparators(@"Characters\Dialogue//Abigail");
// Linux/Mac: "Characters/Dialogue/Abigail"
// Windows: "Characters\Dialogue\Abigail"
|
Semantic versions
Use SemanticVersion to manipulate and compare versions per the Semantic Versioning 2.0 standard. Example usage:
// build version from parts
ISemanticVersion version = new SemanticVersion(5, 1, 0, "beta");
// build version from string
ISemanticVersion version = new SemanticVersion("5.1.0-beta");
// compare versions (also works with SemanticVersion instances instead of strings)
new SemanticVersion("5.2").IsOlderThan("5.10"); // true
new SemanticVersion("5.10").IsNewerThan("5.10-beta"); // true
new SemanticVersion("5.1").IsBetween("5.0", "5.2"); // true
Note that game versions before 1.2.0 and some mod versions are non-standard (e.g. Stardew Valley 1.11 comes before 1.2). All SMAPI versions are standard.
Input
SMAPI's SButton constants uniquely represent controller, keyboard, and mouse button presses or clicks. See the Input page for more info.