Unofficial mod repositories
Host mods for Encore with a static JSON repository
Encore installs mods from BeatMods by default. An unofficial repository is a static JSON file that anyone can host
They're opt-in and disabled until the user reviews the repository and accepts the risk. ScoreSaber can still block individual repositories through its repository policy
How it works
The format is loosely based on VRChat Creator Companion repositories. Read their much better docs here to get an idea.
Each package lists its versions and each version points to a downloadable archive
- The archive and every installed file need a hash. Encore checks both and uses the file hashes to recognise the installed mod later
- Files can only land under
Plugins/orLibs/. A repository can't replace the mod loader or write into the game root
We'll probably want to create some kind of cool GitHub action to automate repository generation from releases or something, not quite sure yet.
Listing format
Serve the JSON file over HTTPS. Encore appends /index.json when the URL doesn't end in .json and converts GitHub blob URLs to raw URLs
Cool thing to add to your README if you wanna, some people may make dedicated encore repo... repos or some people may just do what I did and stick it in their mods existing repo the choice really is yours to make
[Add to Encore](encore://add-source?url=https://raw.githubusercontent.com/example/encore-repo/main/index.json)
<sub>[What's Encore?](https://encore.scoresaber.com)</sub>This opens a preview in Encore. The user still has to accept the risk and select Add repository
The schema:
{
"schemaVersion": 1,
"id": "com.example.encore-repo",
"name": "Example Mods",
"owner": "Example Maintainer",
"contactUrl": "https://github.com/example/encore-repo/issues",
"infoUrl": "https://github.com/example/encore-repo",
"packages": [
{
"id": "com.example.coolmod",
"identity": "beatmods:256",
"name": "Cool Mod",
"summary": "Does something cool",
"description": "# Cool Mod\n\nMarkdown shown in the mod details.\n\n",
"iconUrl": "https://raw.githubusercontent.com/example/encore-repo/main/cool-mod-icon.png",
"category": "gameplay",
"author": "Example Maintainer",
"sourceUrl": "https://github.com/example/cool-mod",
"issuesUrl": "https://github.com/example/cool-mod/issues",
"versions": [
{
"version": "1.2.3",
"gameVersions": ["1.37.0"],
"platforms": ["universalpc"],
"downloadUrl": "https://github.com/example/cool-mod/releases/download/1.2.3/CoolMod.zip",
"fileSizeBytes": 51234,
"hash": { "algorithm": "sha256", "value": "<64 hex characters>" },
"dependencies": ["beatmods:1"],
"files": [
{
"path": "Plugins/CoolMod.dll",
"hash": { "algorithm": "sha256", "value": "<64 hex characters>" }
}
]
}
]
}
]
}Rools:
schemaVersionmust be1- A listing needs
id,name,ownerandpackages. Encore already has the URL it fetched, so the document doesn't repeat it - A package needs
id,nameand at least one version identityis optional and must be a BeatMods mod ID written asbeatmods:<mod id>- A version needs
version, an HTTPSdownloadUrl,hashand at least one file with its own hash - Use
sha256for new repositories.md5is accepted for existing mod metadata - An empty or missing
gameVersionsorplatformslist matches every install. Otherwise the version has to include the current game version andsteampc,oculuspcoruniversalpc - Every file path is normalised like an archive entry and must stay under
Plugins/orLibs/ descriptionis optional Markdown. Encore strips raw HTML and anything other than HTTPS links and images- Optional URLs are only opened or loaded when they're plain HTTPS addresses without credentials or a custom port
- A malformed version or package is dropped. A malformed listing is refused
Package IDs only need to be unique inside their repository. Dependencies refer to another package ID from that repository. Use beatmods:<mod id> to depend on a mod from BeatMods, such as beatmods:1 for BSIPA. The mod ID is the number in its BeatMods page URL
Keep older compatible versions in the listing. Encore uses their file hashes to recognise an installed version and offer the latest matching update under the same repository package ID
Repository policy
ScoreSaber publishes the repository policy at https://encore.scoresaber.com/policy/mod-repositories.json
We'll make this policy editable by trusted figures in the community soon
Hopefully in a not so half assed way where it requires making a commit 🙃
{
"schemaVersion": 1,
"version": 7,
"updatedAt": "2026-07-20T10:00:00.000Z",
"expiresAt": "2027-07-20T10:00:00.000Z",
"transparencyUrl": "https://github.com/ScoreSaber/encore",
"entries": [
{
"reason": "malware",
"addedAt": "2026-07-01T00:00:00.000Z",
"id": "com.example.bad-repo",
"host": "bad.example",
"listingUrl": "https://bad.example/index.json",
"detailsUrl": "https://github.com/ScoreSaber/encore/issues/1"
}
]
}Encore caches the policy in the user data folder and won't replace it with an older version
- A current policy is required to add or enable an unofficial repository
- An expired policy leaves already enabled repositories available but shows that the policy is stale
- With no cached policy, every unofficial repository is unavailable
- A denylisted repository is disabled and can't contribute mods. Denylisted download hosts are blocked too
Encore doesn't come with a bundled denylist. Until the policy endpoint answers, unofficial repositories stay unavailable
Reporting
Once I make the button for it, it'll probably open https://github.com/ScoreSaber/encore/issues/new?labels=mod-repository for now. Proper moderation endpoint's are planned.