Skip to content
This repository has been archived by the owner on Mar 14, 2022. It is now read-only.

Mod Management Specification (Draft) #1

Open
MythicManiac opened this issue Dec 15, 2020 · 42 comments
Open

Mod Management Specification (Draft) #1

MythicManiac opened this issue Dec 15, 2020 · 42 comments

Comments

@MythicManiac
Copy link
Member

MythicManiac commented Dec 15, 2020

Package format

All mod deliverables are to be shipped in a standard package format. The packages are zip files that contain all of the mod's content as well as a small amount of metadata to instruct how the package should be installed.

Currently the following fields for a metadata file in the package are planned:

Field Required Description
Creator ✔️ Name of the team or individual that created the package. Has to be filesystem safe. Used in filepaths and URLs
Identifier ✔️ Name/identifier of the package. Has to be filesystem safe. Used in filepaths and URLs
Version ✔️ The version of the package, following SemVer
DisplayName ✔️ The name of the package purely for display purposes. Does not have to be filesystem safe.
Description ✔️ Short description of the package
License ✔️ The license the package is released and distributed under, using the https://spdx.org/licenses/ format
WebsiteURL A link to a website related to the package
Dependencies A list of required package IDs to install along this package
Tags A list of tags to associated with the package
InstallStrategies A list of strategies to use for installing this package. Strategies are specified separately, and support is up to mod managers.
ExtraData Freeform dictionary of keys/values. Could be used for storing metadata other tools can leverage

Additionally, the following metadata could be included in some shape or form:

  • Package icon
  • Long description / readme

Tooling

Responsibilities of a mod manager

  • Download and cache mods from the internet (where?) to the local filesystem
  • Install packages according to their specified installation strategies

Install Strategies

  • List planned and supported install strategies here
@Absolucy
Copy link

Maybe manifest should be TOML. Easy for humans to write and read, and still easy for machines to parse.

Also, maybe support different compression algorithms for packages? If a mod has the possibility to be big, formats like .tar.zst would be much better for performance and disk space.

@MythicManiac
Copy link
Member Author

Whoops, misclick 😄

@aspenluxxxy we briefly discussed metadata serialization formats on the discord server earlier today, to recap a bit what I remember:

We discussed the possibility of using XML, JSON, TOML, and YAML. Nothing was decided, but I think the points that were made are somewhat as follows:

  • XML
    • Highly structured, support for schemas, etc
    • Boilerplatey to write by hand
    • Annoying to parse
  • JSON
    • Not the best to write by hand
    • Lacking comments
    • Really easy to parse and consume down the toolchain
    • API is likely to be in json already, which means we could display metadata 1:1 in the API
  • TOML
    • Easy to write by hand
    • Still somewhat niche, overall has the worst tooling support of the 4
  • YAML
    • Better to write by hand than JSON or XML
    • Relatively good tooling support

My personal opinion is that we should have a tool that builds the mod packages for us, converting either a YAML or TOML file into a JSON file. We would get the best of both worlds with this strategy, as it allows creators to use the tools best suited for writing configuration while still allowing for easy consumption of the generated package.

@Absolucy
Copy link

TOML's difficulty depends on what the tooling will be made, although I wouldn't mind a converter. As long as it's not XML, I've had enough XML to last me a lifetime 😆

@MythicManiac
Copy link
Member Author

Yeah I've started liking the idea of converting either YAML or TOML to JSON when building the package the more I think about it. It's highly likely we will have a tool that can build and upload packages automatically, so applying a conversion step in that stage would be easy enough.

JSON on the other hand is just so easy to parse with any language that in my opinion it deserves some pretty serious reasoning against using it as the distribution format.

@Absolucy
Copy link

Absolucy commented Dec 15, 2020

License should probably need have the value be a SPDX expression.

@MythicManiac
Copy link
Member Author

That's a very good idea, I wasn't familiar with what the spec is called so good to know. Updated the draft.

@Aelto
Copy link

Aelto commented Dec 15, 2020

YAML also has a downside as mentionned by @avail i think, it is indentation dependent. Making it much more error prone for inexperienced users who may confuse tabs with spaces for example or just anyone who is not aware of this fact.
So in short YAML is easy to read, and (not by much, but still) harder to write.

TOML doesn't use indentation, it can work with it but it is not needed. And as far as i know the language [TOML] has support for parsers in most of the languages, i found libraries in python, csharp, cpp, javascript and rust obviously. Not that this is not an exhaustive list.

JSON could have been the candidate if it had support for comments in my opinion. But sadly it doesn't, unless we use a subversion of the language but again the issue of parsers arises. And i think JSON may appears as verbose as XML for inexperienced users who would like to create a basic mod that has nothing to do with programming.

There is also the INI language (wikipedia page), TOML's ancestor basically. Any language in the world has a parser for it, basic syntax and support for comments too. In it we can add sections, and basic key-value pairs. Making it easy for to edit. Anyone, experienced or not, could edit such a file without risking a parser error.

@MythicManiac
Copy link
Member Author

Good points @Aelto. I think it pushed my vote towards using TOML for the configuration language we write, but I still think we should distribute JSON just because of how prevalent it is nowadays.

At least the python toml library basically hands you JSON as the output if you parse a TOML file, so it would feel natural to ship it as JSON, which overall is a less complex format.

If we were distributing configuration files I would probably vote for TOML in distribution as well, but right now we're talking about something immutable, which is why I think JSON is still best suited for the job.

@Aelto
Copy link

Aelto commented Dec 15, 2020

@MythicManiac

If we were distributing configuration files I would probably vote for TOML in distribution as well, but right now we're talking about something immutable, which is why I think JSON is still best suited for the job.

I agree with you on this point, if the data is immutable there is no reason to use something like TOML and JSON would suit perfectly.

What do you have in mind when you say configuration and distribution? I thought the configuration file was distributed alongside the mod to serve as a small metadata file for the mod manager and the api. Do you intend to have a translation phase where something would convert the configuration file to something the API can read?
And my concerns about the ability to write a configuration file easily could also be bypassed by an interactive tool. An example of what i have in mind is the npm init command, which will prompt the user basic questions about the new project (name, version, author) and will then write the complex json file itself.

So my vote would have been for TOML too, but from what i understand JSON makes everything simpler so i vote for JSON too

@MythicManiac
Copy link
Member Author

MythicManiac commented Dec 15, 2020

I'm not sure if I understand the question correctly, but what I'm saying is that it'd be nice to have developers write TOML, and a tool that builds the mod package zip file to convert the TOML into JSON before placing it into a file inside the zip.

When the mod package gets uploaded to the site, we can validate the metadata json to match the spec we outline here. After the package has been published, we can expose the metadata in the JSON file content-wise 1:1 over the API if we want.

When downstream users download mods, initially they just receive a zip file. Their mod manager will read the metadata json from within the zip file and install the mod according to the instructions. Additionally it can use data from the metadatafile to display mod information in the UI and so on.

So the metadata fields we're outlining here are very much immutable once they're built into a mod package. User-editable configuration file standardization is another topic I suspect we might want to open up in another issue.

Did this answer your question? 😄

@avail
Copy link
Member

avail commented Dec 15, 2020

I think what was suggested was for the devs not to have to write anything manually, but instead have a cli tool (such as npm init) prepare basic variables (author, mod name, [...]) and when packing the mod up the cli tool would take care of mapping the rest

@Aelto
Copy link

Aelto commented Dec 15, 2020

Alright @MythicManiac i understand what you meant now. So there are currently two ideas, use JSON everywhere and create an interactive CLI to ease up the mod creation, or use an easy language for the configuration file that is then translated into JSON. Or both perhaps?

But i must say that i find the idea of translating a TOML configuration file to a JSON configuration a bit much. I'd rather go for the interactive CLI and JSON everywhere route instead, because it's just creating an unnecessary layer of abstraction for the sake of "simplicity" at this point. What do you think?

@MythicManiac
Copy link
Member Author

Either sounds good to me. Interactive configuration isn't incompatible with TOML, but if you feel like using TOML as the in-development configuration format is too much hassle, let's go with JSON.

I'd imagine a lot of people are familiar with JSON based package configurations anyway, given that npm also uses package.json as the main way to configure node modules 😄

@marius851000
Copy link

It might be nice, for dependancies, to add information about how the dependancy could be obtained. This could, for example, be a list of dictionary. Each entry of the list is a dependancy, and each dictionary have at least the key "id" (or "identifier") to specify the id. There then could have a sources entry, with a list of way to get the mod (could be list of string, or a list of dictionary that specify the fetch method and some other data). I image it like:

[
  {"id": "mod1", "sources": [
    {"kind": "http", "url": "http://example.org/mod3"},
    {...other fetch method...}
  ]},
  {...entry for mod2...}
]

having multiple sources would allow to augment reliability if multiple source avalaible but one is not avalaible.

Other possibility (based on https://github.com/OpenMW/openmw/blob/master/docs/openmw-stage1.md)
Entries for license (to specify the mod license, either a predifined common license or a custom string) and languages (a list of supported language).
Creator could also be a list of author in case of mod from a small team.

@Aelto
Copy link

Aelto commented Dec 15, 2020

You're right, we did not think of how the tool would handle dependencies. I don't think the mod author should be able to specify where to download the dependencies, because it could be a potential security hole. Dependency management is always a hard topic to be honest because we always want a decentralized system where any dependency can be downloaded from anywhere, but at the same time we cannot allow the CLI to download files from non certified urls.

I think lots of package managers do it in a centralized way, where the manager decides where to download the archive. Of course we can allow the user to register other mod repositories, but it is done by the user and not on a per-mod basis and by the mod authors.

@marius851000
Copy link

marius851000 commented Dec 15, 2020

Having some formatting for the description would be nice. Maybe some markdown. Could allow to include picture, at the cost of rendering complexity (html would work, too, but then it would be uselessly harder to render).

@Aelto After a bit of thinking, I came to this idea :

When listing dependancy, also have a list of remote that have this dependancy. They could be identified by domain name, digital signature, or some other thing.

This would allow the user to allow or block some remote (using an allowlist). When adding a mod, the mod manager see if the dependancy is in one of the allowed remote. If not, it ask the remote specified by the depency if they have it. It then list the remote who have the depency, and allow the user to select one, that could either be permanently trusted or only trusted for this one depency, or finally do not download it at all (and let the user fetch it himself).

This should be both secure, and allow mod to specify the location of mod without needing the user to search what remote have the depency (or have a list of default depency remote already allowed -- or at least making the choose to allow or not some remote by default less biased due to will some random mod added via github or similar work out of the box)

@MythicManiac
Copy link
Member Author

Having some formatting for the description would be nice. Maybe some markdown. Could allow to include picture, at the cost of rendering complexity (html would work, too, but then it would be uselessly harder to render).

My idea was that the description is a short description (think 250 chars or so) that can be included in small UI spaces. On top of that we could standardize longer descriptions e.g. a README.md to ship with tha packages that could have any amount of other content, or even more advanced solutions whatever we come up with. Either way I'd imagine there's value in having a short description that can be shown in smaller UI spaces.

Regarding the download sources
Whatever way we go, I think it's fair to say we should at least have a default source. Also should be mentioned that if we want to support more sources than one (which honestly is a good idea for the health of the ecosystem), we need to take that into account when namespacing packages. For example, it's now assumed that author names are globally unique, but if we introduce packages from other remotes, that might no longe hold true.

@Aelto
Copy link

Aelto commented Dec 15, 2020

@marius851000, an issue was created for directo discussion about the CLI tool itself. If you would like to continue discussing the interesting subject you brought up, i think it would be better suited in the issue #2 about the Game Package Manager tool (the cli).

And i agree that your idea of allowlists and denylists (or whitelists and blacklists if we use the old and now outdated terms) should solve the issue. And the way you presented the solution seems like a perfect solution. An allowlist where the CLI prompts the user about new unknown hosts is perfect for this case.

Do you think the CLI tool should have a command to easily manage the lists, like allowlist add <host> and the same the remove. Or should we just use the prompt that comes when a new unknown host is discovered?

Please, quote and answer this post in the other issue as i completely forgot to do it myself 👍

@marius851000
Copy link

marius851000 commented Dec 15, 2020

@MythicManiac I effectively see the issue that mod1 depend on mod2 that is hosted on service1 by the user named user1, but then, on the service2, also allowed, a malicious user register the id mod2 with it being a malicious version of mod2.

I think I have an answer for that :
assuming mod id on services are like domain name (first to register get the id for the service, at least until the service shut down), we could have mod1 depend on either service1/mod2 or service2/mod2_legit (or just ask admin of service2 to remove the malicious code and link it to mod2_legit). So, we would need to check the presence only on service allowed by the mod, and install only from service allowed by both the user and the mod (or maybe some service allowed by the user with the remote specified it can serve as fallback, but that will assume that the remote check and trust every published mod on its service).

@Absolucy
Copy link

Could allow mods to be signed with ed25519 keys, and hardcode the public key into manifest files. So only download mod2 if it can be validated with pubkey2, which is specified by the dependant

@marius851000
Copy link

(ed25519 is an asymetric digital signing method)
@aspenluxxxy
Seem also a good idea, and would allow for update (as opposed to hash) (but can lead to some complexity if the private key is hacked). We should take into account the possibility of revoking a public key for this.
When you are speaking of manifest file, you speak of data delivered with the original mod (not remote depency), right ?

@Absolucy
Copy link

When you are speaking of manifest file, you speak of data delivered with the original mod (not remote depency), right ?

Yeah, the dependency field could specify "only grab the dependency signed with pubkey"

@MythicManiac
Copy link
Member Author

One obvious downside to multiple sources is identification of identical packages. I don't think it's too far fetched to assume mod authors might serve their mods from multiple different sources, (e.g. github and the default repository), and if we no longer can match packages by package identifiers (which is a problem introduced by multiple download sources), we will need some other way to detect content-wise identical packages.

It would be troublesome to have package A depend on package C from source 1, and have package B depend on the same package C from source 2. With the proposed solution we would have to treat both dependencies as unique, even if they were the same package.

Now, you might think we could easily solve the issue by including somthing like a hash/signature as the package ID and avoid duplicate package installs that way, but how about if we try to do version range dependencies?

I'm sure we could come up with a technical solution to make multiple package sources work as expected, but I'm starting to wonder is the extra complexity worth it, or should we sacrifice some integrity guarantees in favor of simplicity?

Maybe we could always depend on a identifier only, and allow for listing of more download sources. We would then have the manager download packages from the first repository it finds that matches the package name, and the repositories could be priority ordered. Something akin to what system level package managers do on the linux world.

@Aelto
Copy link

Aelto commented Dec 15, 2020

You're right @MythicManiac. Maybe the simplest solution is to create a centralized repository and offer the support for optional repositories. But if the user chooses to use another repository it's his own choice and we should not make everyone's life more complicated just because we support 3rd party repos.

Maybe we could make it in a dumb and simple way, if a mod is in a mod repository it means all of its dependencies are from the same repository. Roughly the same idea that mastodon (the decentralized twitter) uses for its instances. An instane is basically a independant version of the database, and it's up to the instance manager to synchronize the new instance to the other instances if they want to.

It may not be realistic to think about a fully decentralized solution inside our CLI at the moment. The CLI should stay simple and do one thing, store an address for the current mod repository and then download everything from it.

@marius851000
Copy link

marius851000 commented Dec 15, 2020

@Aelto @MythicManiac
It might indeed be a good idea to have:

  • a/some default allowed remote
  • none/a/some user allowed remote
  • when wanting to know if two package are the same (but with maybe a different version):
    • just compare the id
  • when searching for a package:
    • query all allowed remote for the id
    • select one of the remote (first priority: the most up to date version that correspond to a potential filter, second priority (with multiple up to date remote, remote order)
  • installing package :
    • search the id
    • install it, assuming all depency are on the same remote
  • installing package from a source that isn't a remote (directly a zip):
    1. do not include the possibility to use remote. The user should first add the depency himself
    2. include the id of the dependancy. Will be searched and added if avalaible
    3. same as upper, but allow the package to specify a list of remote that should contain the id (should be usefull if the mod depend on another unstable version of a mod)

Also, Will assume the same mod can't have multiple enabled version.

also, the linux distro I use actually hash the version, package name and all the build instruction together to generate an hash that will identify the package -- allowing multiple version of the same software to be installed. If your interested, it's called nixos.

This actually assume that a mod with the same id on multiple remote correspond to the same mod.

@marius851000
Copy link

about InstallStrategie:
We need to find some way to specify which method is used. I propose this field to be a list of dictionary, but those dictionary should contain an key "type" which specify the installation method (the value is a string). The rest of the dictionary is indeed freeform

@Aelto
Copy link

Aelto commented Dec 16, 2020

Exactly, so the idea is that it's up to the user to use a different remote than the default one. But it is not the mod author's responsibility to do it. Did i understand correctly?

And i don't think we could compare two packages from two different remote instances, even with an ID or a GUID or anything because we cannot know if the instance manager changed the files in a malicious way without changing the IDs. Maybe comparing hashes to check the file integrity could solve the issue though

Can you give example of various Install strategies you suggested? I can only find http and disk as two possible values, is there any other value you have in mind?

@MythicManiac
Copy link
Member Author

MythicManiac commented Dec 16, 2020

about InstallStrategie:
We need to find some way to specify which method is used. I propose this field to be a list of dictionary, but those dictionary should contain an key "type" which specify the installation method (the value is a string). The rest of the dictionary is indeed freeform

I was thinking the InstallStrategy would simply be a list of install strategy identifiers, but you probably were thinking the dictionary would contain parameters for the install strategies too?

My thought process is that the package standard itself should not care what the install strategies do or what their parameters are, we just need to know what strategies the package is flagged as supporting. The install strategies themselves can have their own specs on how to define parameters; some could be entirely parameterless and function by convention, where others could have their own metadata files.

For clarification, an Install Strategy is an identifier for the logic to use to extract/install the package into the game. The goal is to not lock in how packages are actually installed in the package specification, and allow the expansion of those rules and methods later on without requiring a package metadata change.

An example is how the current packages define the following metadata:

"extra_data": {
    "mm_install_strategy": "extract-gamedir"
}

I've hardcoded the MythicModManager to identify packages that define their mmm_install_strategy to be extract-gamedir, and have a special way of handling them as opposed to the default behavior. This way we can separate the responsibility of how a package is installed from the required metadata while still keeping it as a valid information source on how to install a package.

@marius851000
Copy link

marius851000 commented Dec 16, 2020

@Aelto We should actually be able to compare mod from multiple different remote if we trust them all (and we keep the default list small). Including the hash shouldn't be a good idea, as it would prevent update to the mod (but asymetric cryptography could work at the cost of complexity). I suppose the idea of trusting every allowed remote is good, as from the moment you download any mod from one of this website, the mod could allow Arbitrary Code Execution.

@Aelto
Copy link

Aelto commented Dec 16, 2020

Yes, what scared me first was the fact the mod authors could specify remotes on a per mod basis or that a mod could have dependencies on different remotes too. But if we exclude these ideas, i don't see any issue with downloading packages from different remotes too. Except that it could create fragmentation in the packages world, but that is the cost of decentralization i suppose. And if we keep a nice and frequently updated default store there should be no issue.

But i really don't see the point in comparing packages from different remotes. Unless we want the stores (remotes) to be able to synchronize their packages

@marius851000
Copy link

marius851000 commented Dec 16, 2020

@Aelto comparing depency is usefull for when some remote are not up to date (althought limiting fetching dependancy from the same source as the mod is a good idea if the source is a store -- as opposed to a manually downloaded .zip file).

Another use case could be using experimental package. The user just add a dev remote by the mod author, and tada nightly/whatever unstable release. Also, I suppose it is useless to specify that we only download depency if they are already installed locally (and no update are avalaible).

@Aelto
Copy link

Aelto commented Dec 16, 2020

It seems to me the way you would handle nightly-releases for dependencies is wrong. Are we going to create a remote just for nightly releases or will we ask every single author to create their own remote that the user will have to validate just for their nightly-release?

I think we should manage nightly releases differently, i don't know how yet, perhaps in the version property when specifying the package you want to install like package-name: 0.1 and package-name: 0.1-nightly. Or maybe a new boolean property altogether. But that is for another topic.

And okay, yes i understand now why a way to compare packages between two remotes is expected. So how will it work, first it will fetch the package by its package-name, then compare the version, and finally synchronize it? Something is still missing from here for me, i think i need help figuring out a proper way to synchronize packages from two different remotes.

@MythicManiac
Copy link
Member Author

I think the most popular way to handle this kind of scenarios is to synchronize the available package index from each configured remote, and check which one(s) have the most latest versions available. This however does mean we'll idelly need a local package index cache that we can use to look up packages (think apt-get update). Then we could check the local cache for the latest version and use that.

@marius851000
Copy link

@Aelto @MythicManiac About the index: Assuming the number of mod to install in one go should be pretty small (the number of mod to install should be of some at a time) and we have a small number of remote (let's say 5) this shouldn't be too much of an issue to make 20 http query. The number of request augment linearly with both the number of mod to install and the number of remote. So having to have a local cache might not be required. Just query the version the remote have for each of those mod (or compact that in one http request, like tell me what's the version(s) of mod1, mod2 and mod3 you have), and select the remote to download each mod based on that.

As for nightly handling: making it part of the the version doesn't seem a good idea, as we may want to rather use the first 7 seven character of the git revision, as is commonly done. As for the name, this could lead to some complexity for handling depency (mod1 a depend on mod2, but mod2-nightly is installed (and so shouldn't install mod2 from remote)). I think the idea of adding a boolean to specify if this is nightly or not is a good idea. Will need to manage the possibility that there are multiple version of the same mod avalaible on the same remote, but then, we can just let the user opt-in to the nightly with some flag linked to the package ID)

@Unnoen
Copy link

Unnoen commented Dec 19, 2020

As someone fairly active in various modding communities, my suggestion would be to look at MinecraftForge's mod info/versioning file:

https://github.com/MinecraftForge/MinecraftForge/blob/1.16.x/mdk/src/main/resources/META-INF/mods.toml

Mainly three things:

It supports multi-mod-single-archive mods, this would be useful for authors who modularise their mods but would like to offer an "all-in-one" solution.

It has explicit support for dependencies and if they're mandatory or not.

And lastly, the version spec is that of Maven's which supports a whole range of different things. From the basic 1.0.0 to something like 1.0.0-beta.0.0 or 1-nightly. As well as ranges.
(A quick example of version ranges: https://www.baeldung.com/maven-dependency-latest-version#maven-version-range-syntax)

Of course, this is merely a suggestion that aims to help with figuring things out, and implementing some of these things may be too much for right now, but I thought it would be a good example of something used in another unofficial modding API/toolset.

@MythicManiac
Copy link
Member Author

Version range support for defining dependencies seems important to have, this was also just commented on #2 (comment)

For the version numbering scheme, I have a small soft requirement, which is that it should be possible to parse the following information from a "full" package name, and that the full package name should be filsesystem safe:

  • Package Creator
  • Package Identifier
  • Package Version

The full package name would be formed by {creator}-{identifier}-{version}.

This is not a hard requirement, but it will give us some nice guarantees, e.g. that we can place all packages downloaded into a single package cache side-by-side without worrying about collisions, and that we can simply by looking at the filename determine what package is in question. The bigger picture philosophy is that packages are namespaced by the creator's identifier, akin to how repositories work in GitHub.

@halgari
Copy link

halgari commented Dec 19, 2020

I'd like to throw out there that a lot of this will be dependent on what services you plan on using. I've spent the last 16 months or so building a community around a project like this for the Bethesda game community. Wabbajack (https://github.com/wabbajack-tools/wabbajack) has had to handle a lot of these sorts of issues. In that time we've seen 100k installs using the software and about 40k users.

While I'm all for adding support for Cyberpunk to Wabbajack, I recognize that green-field development can also have its perks.

I would however recommend keeping version numbers string-free and machine readable. If you are going for {creator}-{identifier}-{version} put them in separate fields: "creator": "halgari", "identifier": "no-quicksaves", "version": "1.0.42". One of the biggest mistakes you can make on a project early is making something that could be machine readable into something only a human can parse. What if a user puts a - in the name? If you used the above info you'd now have halgari-no-quicksaves-1.0.42 and now a machine doesn't know if the name of the mod is no or no-quicksaves.

@nihaals
Copy link

nihaals commented Dec 19, 2020

Related: thunderstore-io/Thunderstore#138

In my opinion, requiring a $schema field helps build a strong standard, but I see that plenty of other very popular formats don't have it as the file name is effectively owned (e.g. package.json) which seems to be the goal of the manifest file

People may be confused when viewing a manifest in a Git repo as there isn't any real link so it might appear to be a project specific file instead of a file used by a mod repository. If an install link is included in the README and the user looks at other mods they may realise that the file is a standard

Some other file names are very explicit (e.g. docker-compose.yaml) which means there's less likely to be a collision and simply Googling the file name will help (I think the Google-ability of the file name is pretty much the end goal, if you just Google package.json you find everything)

In the short term, $schema could help make the standard grow and make it clearer to readers, but in the long term if it manages to become well known, it will just seem unnecessary (I guess it could become optional in a future version but formats are meant to last a long time)

@nihaals
Copy link

nihaals commented Dec 20, 2020

Would there be a set list of tags or can users select any tag they want? Would it be A-Z a-z 0-9 - <space> _?

@MythicManiac
Copy link
Member Author

I would however recommend keeping version numbers string-free and machine readable. If you are going for {creator}-{identifier}-{version} put them in separate fields: "creator": "halgari", "identifier": "no-quicksaves", "version": "1.0.42". One of the biggest mistakes you can make on a project early is making something that could be machine readable into something only a human can parse. What if a user puts a - in the name? If you used the above info you'd now have halgari-no-quicksaves-1.0.42 and now a machine doesn't know if the name of the mod is no or no-quicksaves.

Agreed, keeping things parseable is a requirement. I was merely suggesting that in addition to keeping the fields separate, we can have guarantees in place that allows the use of a single-string identifier (by ensuring all components can still be parsed from it). If we look at the way Thunderstore for example handles things, the guarantee currently exists.

Would there be a set list of tags or can users select any tag they want? Would it be A-Z a-z 0-9 - _?

I'd say tags are just a list of arbitrary strings, so no list of set tags. We can restrict characters to something sane like proposed, though I'd allow at least : and . as well

@MythicManiac
Copy link
Member Author

On second thought I don't think we need to restrict tag characters either, my biggest concern allowing anyting would be if someone adds zalgo there or some super weird utf-8 characters. No idea what the allowed character set should be like to only leave out the weird stuff.

@scriptxotic
Copy link

Hey guys you might want to grab some ideas from this package manager:
https://github.com/lukesampson/scoop

The description and bucket system seems to be quite straight forward !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants