Loadout and Library Items
Context and Problem Statement
The data model of Loadouts containing "Mods", and "Mods" containing Files is inadequate. The definition of a "Mod" is ambiguous and leads to miscommunication and misunderstanding. A mod manager is supposed to manage mods, but we're doing much more. In this subpar data model, "Game Files" and "Overrides" are also considered to be "Mods". Any additional features would need to be shoehorned into the definition of a "Mod" resulting in convoluted design implementations and backend data queries.
The Solution
Instead of trying to force the use of "Mod", the decision was made to use "Loadout Items". A LoadoutItem
is just that, an item in a Loadout with a name. Expanding on this, we have LoadoutFile
which represents a file and includes LoadoutItem
. There are many more subtypes of LoadoutItem
and extensions are free to add more as they see fit. Another core type is the LoadoutItemGroup
. This type itself is also a LoadoutItem
and any LoadoutItem
can be part of a LoadoutItemGroup
:
erDiagram
Loadout
LoadoutItem
LoadoutItemGroup
LoadoutItem }|--|| Loadout : references
LoadoutItem }|--|| LoadoutItemGroup : references
LoadoutItemGroup ||--|| LoadoutItem : includes
This model is a tree structure and allows for arbitrary grouping of items. Previously, we'd run into issues where one archive might install three SMAPI Mods. The previous model would struggle here since the user expects one "Mod" to appear, but we installed three. The new model doesn't have this issue, as you'd get one "top level" group containing the three SMAPI Mods.
Another important part of our data model is the Library. Previously named "File Origin Registry", it was a complete mess of hacked together models representing downloads. The relationship between the Library and Loadouts was also difficult to understand.
As a counterpart to LoadoutItem
, the new model has LibraryItem
. This represents an item in the Library. Further classification is possible, and the model has additional types like LibraryArchive
for archives in the Library. Similar to the situation with "Mods", the old model tried to shoehorn everything into the definition of a "downloaded archive".
The link between the Library and Loadouts with the new model is very clear with the new LibraryLinkedLoadoutItem
type that directly references the LibraryItem
that the LoadoutItem
is linked to.
Impact
Besides reducing the amount of technical debt and hacked together code that was very convoluted and unmaintainable, the new types allow for easier and precise querying of relevant data. Installers can easily create subtypes of LoadoutItem
, and diagnostic emitters can easily query those and use the data provided by the installers.
Implementing designs is also made much easier for the same reasons. Many queries can be abstracted and UIs can be unified to show the same data across the entire App. This allows us to implement more complex designs that were previously not feasible.