Core Library
StardewUI's Core Library is all of the mundane, engine-room components and functionality running underneath the magic of the framework.
When you display a view written with StarML, the framework does not translate that directly to pixels on the screen; instead, it is transformed into a view tree—a hierarchy of layout views and content views, which handle everything that isn't related to data binding.
StardewUI Views are identical in concept to Qt widgets, Android views or HTML elements; they are responsible for performing layout, handling user interaction and ultimately drawing themselves to the screen, or SpriteBatch as is used in Stardew Valley.
Features
Core library features are loosely divided into the same categories as code namespaces:
- Graphics: Abstractions for game sprites, the MonoGame SpriteBatch, and everything else that deals directly with "pixels on the screen".
- Input: A variety of useful tools for dealing with user input (text entry, button repeat/throttling, etc.) that Stardew Valley and SMAPI don't provide themselves, or hide behind implementation details.
- Layout: Essential types and tools for describing layouts: positions, alignments and other dimensions.
- Widgets: All the standard views.
- Overlays: System for displaying views as either dismissable overlays, such as dropdowns, or full-screen ("modal dialog") style, such as the keybinding editor.
- Animation: Tools for animating properties of views. Includes the Transition and KeySpline used for framework transitions, and some legacy specialized non-framework utilities such as HoverScale.
- Diagnostics: Primarily performance tracing.
Usage
When you use the UI Framework, the Core Library is designed to work behind the scenes. However, there are some cases when you might need to use it directly, e.g. if you are writing extensions.
Unless you are specifically opting out of all framework features, the correct way to reference the Core Library is via SMAPI's ModBuildConfig, which most mods should normally already be using; the reference can be added either directly, or indirectly via ModManifestBuilder.
Using ModManifestBuilder
Simply add the reference to your .csproj
file using SMAPIDependency
, and set the attribute Reference="true"
.
Example
Using ModBuildConfig
SMAPI defines a GameModsPath
variable which you can use to reference the StardewUI assembly relative to the game path, instead of a physical directory on your machine:
Example
Note that when you add a direct assembly reference—as opposed to the more common API integration method—it is extremely important to also add the mod as a required dependency in your manifest.json
, otherwise SMAPI may not load the mods in the correct order, resulting in your mod failing to load, and this failure may be intermittent or platform-specific, e.g. loads correctly on Windows but not Linux or vice versa.
Example
These instructions only apply to the ModBuildConfig
method, because ModManifestBuilder
does it automatically for you.
Although MinimumVersion
is optional for manifest dependencies, you should always include it for any StardewUI versions prior to 1.0. StardewUI follows semantic versioning and any versions prior to 1.0 are considered development versions that may introduce breaking changes.
Using Submodule/Shared Project
Danger
Submodule/shared project imports are only for users who are not interested in any of the framework features, and need a completely standalone solution for their project.
Visual Studio Shared Projects are a 10-year-old technology that has never been clearly documented; the best resources available are a few obsolete documentation pages and blog posts. They do work, and are fairly common to see in Stardew Modding Monorepos, but have many quirks, tend to behave oddly and in frustrating ways within the IDE, and most importantly, are compiled as your own source code, meaning they generate new types inside your mod and are therefore not compatible with the types inside StardewUI.dll
. If you try to use them together, you will run into cryptic errors like No value converter registered for Edges -> Edges
.
Git submodules (AKA "sob modules") have many problems of their own and are widely hated for many good reasons. An alternative is git subtree, which solves some but not all of the problems of submodules, and solves none of the problems of Shared Projects.
Consider carefully before choosing this option, because it may complicate your project maintenance and is effectively exclusive with the Framework; you can only use one or the other, and switching to the Framework later on may be difficult if there have been breaking changes, or if you depend on any internal types.
If you have elected to use the Core Library Shared Project (please read the warnings above) then use the following process for including it:
cd
into your mod's solution directory.
(This is the directory containing the.sln
file, not the.csproj
)- Add the submodule:
git submodule add https://github.com/focustense/StardewUI.git
- Add the shared project to your solution. In Visual Studio, right-click on the Solution in the Solution Explorer, then Add -> Existing Project..., find and select the
StardewUI.shproj
inside theStardewUI\Core
folder created in step 1. - Add a project reference to your mod. In Visual Studio, right-click on on your Project (not the solution, and not the StardewUI project; the project for your mod), then Add -> Shared Project Reference, and tick
StardewUI
. If you don't seeStardewUI
in the list, then you made a mistake in one of the previous steps. - Double-check; if you open your
.csproj
file in VS or a text editor, it should have the following line:<Import Project="..\StardewUI\Core\StardewUI.projitems" Label="Shared" />
Once imported, you can reference StardewUI's types directly, including ComponentView and ViewMenu which are the entry points for most user-defined views and menus, and what the Framework uses internally.
A few other considerations and tips for shared project users:
-
Since you are depending on the source code, expect things to break if you update (pull).
While there is still some risk of this even when using the other, recommended methods, breaking changes to the Framework/API should normally be reflected in the project's semantic versioning, whereas potentially breaking changes to the source will not. If you fork or modify the shared project in any way or use any of its
internal
types or members, there is a good chance that your solution will no longer compile after an update. -
If you update/pull the shared project, and Visual Studio starts behaving strangely (not showing the correct files, producing compilation errors that make no sense, etc.), try closing Visual Studio, deleting the
.vs
folder inside your solution, and reopening it.The exact nature of this bug isn't clear, but sometimes Visual Studio, MSBuild, and even the
dotnet
tool can keep holding onto old state, even if you clean and rebuild. Deleting and re-importing the entire submodule will not fix the problem, but deleting.vs
usually will.
Why use a submodule/shared project?
With all the ominous warnings above, you might be wondering "why would anyone use the submodule/shared project method?" There are two reasons why this usage is still available and (somewhat) supported, despite being strongly recommended against:
-
You want to avoid any dependencies in your mod for personal or philosophical reasons. If you are offended by the idea of depending on GMCM, SpaceCore, etc., then you might not want to depend on StardewUI either.
-
You don't plan on maintaining your mod long-term, and want to be immune from any future changes to StardewUI; i.e. you're willing to trade off the benefits of any new features, bug fixes, performance improvements, etc. for the guarantee of not being broken by outside changes.
While your users would undoubtedly prefer that you maintain your mods, and most users really do not mind adding one more shared dependency to their mod list, we recognize that this may not suit all authors, which is why the shared project is only "soft-deprecated" and not officially obsolete or removed.