Open MythicManiac opened 5 years ago
As far as version range goes, I suggest we just use the semver versioning scheme. It can handle anything you through at it, and is widely used.
NetworkMode: Where is this code required to run for the mod to function?
server
,client
, orboth
I'd like to propose a none
/ nosync
mode, similarly to how it already is implemented by the Terraria modding community. This would be important if the network mode ever gets enforced in a strict manner, f.e. clients disabling their server mods automatically and servers syncing their client mods with connecting clients.
@0x0ade I feel like that could be it's own separate field, and good point 👍 The NetworkMode
could be used purely to define where the mod functions/is required, and maybe some separate flag for whether or not the mod should be sent to clients. At least in my mind those are different use cases, and could use separate fields due to that.
Loader: What loader should load this mod? Freeform input, currently likely disunity, bepinex, monomod, or empty
Will this field be an array? As R2API contains both a monomod
patch and a BepInEx
plugin.
@tristanmcpherson good point, we'll have to think how to handle that as well. With the current spec it could be workarounded by separating those to two packages, and having a dependency relation, but it would probably be nicer to do that in a single package.
Key capitalization. Generally JSON formatted data uses camel case key names, although technically using pascal case isn't explicitly forbidden. Just throwing it out there since it's somewhat unconventional.
PackageType
values need clarification and are possibly missing a mod
value. What's the difference between framework
and library
? What category do mods fall under? What about a mod that provides a scene hierarchy view?
Could the Loader
field be determined from the dependencies?
Ability to specify a required dependency that can be fulfilled by more than one mod. Perhaps a pain to implement, but what if a certain requirement of a mod can be fulfilled more than one mod (especially if they conflict)?
GameVersion
could be merged into Dependencies
and the game itself could then be made into a meta package, but honestly I feel like this one isn't really necessary. Still, throwing it out there.
GameVersion
could also be a version range. Mod managers are likely going to end up using that field for determining mod compatibility with the game and obviously some mods might stay compatible between game versions. Then again, bumping the supported game version could be considered in semver terms a change that would warrant a mod version bump.
Another thought: characters allowed in Name
and possibly AuthorName
should be declared in the specification, both because right now it's vague at best and as they're most likely going to end up in URLs. Something to consider here would be names potentially used by Asian users but also just straight up zalgo.
I was under the impression that this is a manifest for mod repositories (more specifically Thunderstore, which I've heard is trying to keep it possible to potentially reuse its code for other games, i.e. not RoR2) that would also be used by mod managers to install the mods. That means that while taking the existence of Disunity (and other loaders) into consideration, this manifest isn't actually a Disunity manifest.
Now, based on what I've learned about Disunity, it will be taking into consideration mod repositories and will provide its own solution for those, so we end up with a problem: Thunderstore is trying to stay loader agnostic while Disunity is trying to be, in a way, Thunderstore.
I see several possible outcomes of this situation:
Thunderstore has its own manifest for mod packages, stays loader agnostic and supports Disunity as well as other loaders (which is the way I believe Thunderstore wants to go, considering this conversation). Downside is mod developers juggling multiple manifests and repeating information.
Thunderstore and therefore the mod managers start supporting the Disunity manifest. Information isn't repeated but managing all this information by the store itself and mod managers becomes a mess (could potentially be solved by Thunderstore keeping a manifest format of its own which would be automatically generated using the Disunity manifest). This provides support for non-Disunity mods.
Thunderstore adopts the Disunity manifest format and becomes the first Disunity-specific mod repository. Downside here being the lack of support for other loaders such as BepInEx, which are currently commonly in use by the community.
Key capitalization. Generally JSON formatted data uses camel case key names, although technically using pascal case isn't explicitly forbidden. Just throwing it out there since it's somewhat unconventional.
This is what I thought too, and also why they are so in the table above. Another question entirely is should we even use JSON or not? There's been some hopes for alternatives, e.g. TOML, YAML, or even XML. This is an open point for discussion, feel free to contribute your thoughts.
Personally I think that either of the two following criteria should be met:
PackageType values need clarification and are possibly missing a mod value. What's the difference between
framework
andlibrary
? What category do mods fall under? What about a mod that provides a scene hierarchy view?
I thought I had mod
in there, but evidently not, good eye. Framework can be removed if it's seen as unnecessary, I was thinking bepinex/disunity/monomod would fall into this category.
Could the Loader field be determined from the dependencies?
- What happens if the mod has both a monomod prepatcher and wants to be loaded using bepinex?
- What if the mod can be loaded using more than one mod loader for compatibility?
I believe this is what's currently being done to some extent, but I think we should standardize this more to have a more reliable system.
It does seem we should add support for N amount of mods in a package, targeted at N2 loaders. How should this be in the spec is currently open for discussion at least, but a simple path mapping should suffice I think.
Another alternative is that we only allow one loaded entry per package, meaning if you need more, you'd add dependency relations. I don't think it's as nice of a solution, albeit "cleaner" in a sense.
GameVersion could be merged into Dependencies and the game itself could then be made into a meta package, but honestly I feel like this one isn't really necessary. Still, throwing it out there.
This schemantically doesn't make much sense to me at least, given how dependencies are an entirely different datatype.
GameVersion could also be a version range. Mod managers are likely going to end up using that field for determining mod compatibility with the game and obviously some mods might stay compatible between game versions. Then again, bumping the supported game version could be considered in semver terms a change that would warrant a mod version bump.
Could of course. Would you think that's going to be useful? The need I imagined for this field was simply to know what game version was the mod built for (e.g. after a game update, is the mod targeting the latest version already or not). Allowing for version ranges would at least need to be limited so you can't target a range upwards, as that would make this kind of usability not work (we can't know what happens between game updates, so we can't guarantee it will work on the next version).
Definitely open for more discussion.
Another thought: characters allowed in Name and possibly AuthorName should be declared in the specification, both because right now it's vague at best and as they're most likely going to end up in URLs. Something to consider here would be names potentially used by Asian users but also just straight up zalgo.
Agreed. If we end up using a format that allows schema validation, it's easy to ship that schema on top of any documentation. The biggest limitation is that the names have to be filesystem safe, as defined by Windows (since other platforms are more lax on those anyway).
Tags were mentioned as well in conversations, should think if those are fine to be added here or some other system.
Consider adding an optional Deprecated
field.
On that note, if you do so, please consider using that field to link alternatives.
Let's add a field for license as well
EDIT: Added to the spec
Loader
should probably be an array of Loaders
instead, as a single mod can possibly have multiple loaders.
Why is ExtraData
necessary? Why wouldn't you just have additional root-level keys? Manifest version will ensure these are ignored if a new version uses those same names, and the only benefit of using ExtraData
would be that you could then have keys that have the same name as root-level keys in the same manifest version. (which is stupid and confusing, and should be discouraged anyways)
Why is
ExtraData
necessary? Why wouldn't you just have additional root-level keys? Manifest version will ensure these are ignored if a new version uses those same names, and the only benefit of usingExtraData
would be that you could then have keys that have the same name as root-level keys in the same manifest version. (which is stupid and confusing, and should be discouraged anyways)
Two reasons I can think of immediately are:
ExtraData
, as it'd be reserved for 3rd party useThe intention is providing a way for 3rd party metadata to be included in the manifest, though the exact schema is likely to change too. If a 3rd party tool needs complex metadata, it can require it's own files. Whatever we have supported for the manifest is likely going to be something that gets indexed by the site and will be visible in the API as well (e.g. for search purposes). How that'll happen in practice is still not decided, but it's something we want to make happen.
An example scenario where this is useful would be a custom map loader. It could have it's own metadata convention in the manifest, and display available maps (via Thunderstore API) in-game based on metadata filters.
Currently, the Risk of Rain 2 mod tooling economy is very unstandardized, which causes confusion among mod developers on how to make mods, users on how to install mods, and tool developers on how to manage mods.
The goal of the Manifest v2 specification is to allow for more flexible yet standardized support for mod packages. The Manifest v2 specification should account for the needs of users, mod developers, and tool developers, while being flexible enough to function for the foreseeable future.
Based on #86, I have now collected the following spec for version 2
v2 specification (subject to change)
2
in this case.server
,client
, orboth
code
,tool
,mod
,map
, orother
extract
,managed
, ornone
disunity
,bepinex
,monomod
, or emptyClarifications
extract
: The package should contain a folder in a standard location, which will be extracted directly on top of the game directory. This mode of installation will allow for overwriting of files, or installing tools such as bepinex or disunity.managed
: The package should be managed by mod managers, according to theloader
field, or however the manager otherwise sees fit. This means that mods that are defined as managed may not know where they are placed, as that is the responsibility of the manager. Future development will allow us to standardize one way for handling all managed packages, instead of the current system where it's loader dependant.none
: This package should not be installed to risk of rain. Used for packages such as mod managers for example.Todo
Next steps after v2
Please do share any concerns and/or suggestions