A shared store of static mod files, linked into instances
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by reading the implementation from #72, especially ModLibrary.AddMods and ModEntry.Exists, plus the current recursive instance-deletion path. The issue specifies Windows junctions, Unix directory symbolic links, private-copy fallbacks, and lifecycle behavior; use its listed tests to verify discovery, reuse, removal, and writable-mod handling. Done means shared releases remain immutable and are removed only after their last reference, with unresolved writable-mod and store-key decisions addressed.
Written by the indexing model from the issue text.
Description
Where this stands today
#72 installs a release by unpacking its archive into the instance's mods folder.
A mod used in three instances is stored three times. Each instance also downloads and unpacks the archive again when it updates to the same release.
Proposed design
Keep instancing.
Store the static files of each mod release once, under a path such as Borea\Static Mod Files\<Mod>\<Version>.
Create Instances\<Instance>\mods\<Mod> as a directory link to that stored release:
- On Windows, use a junction when the link and target are on supported local filesystems. Windows junctions can point to another local volume, so the two paths do not have to use the same drive letter.
- On Linux and macOS, use a directory symbolic link.
- If the platform, filesystem, or target location does not support the required link, copy the mod into the instance instead.
Microsoft documents that a Windows junction can point to a directory on another local volume, but not to a mapped network volume or directly to a file. See Hard links and junctions.
.NET provides Directory.CreateSymbolicLink for symbolic links. A Windows junction needs a small Windows-specific implementation behind the same Borea directory-link abstraction.
Writable mods
A shared directory exposes every write to every instance that links to it.
A mod that writes into its own installation directory must use a private copy instead. An in-game part maker, for example, can change its own meshes or textures and must not share those writable files across instances.
How a mod declares this remains open. An index field requires an RFC. A Borea-owned compatibility list can be a temporary solution.
Install, update, and removal behavior
| Operation | Required behavior |
|---|---|
| First install of a static release | Download, verify, and unpack the release into the shared store, then link the instance to it. |
| Install of a release already in the store | Create the instance link without another download or extraction. |
| Update to a stored release | Replace the instance link without changing the stored release. |
| Uninstall from one instance | Remove only that instance's link. Keep the shared files while another instance references them. |
| Delete an instance | Remove its known mod links before recursively deleting the remaining instance directory. |
| Remove the last reference | Remove the stored release only after no instance references it. |
| Install a writable or unsupported mod | Copy the files into the instance and manage them as private files. |
Stored release directories are immutable. Borea must finish download, digest verification, extraction, and mod-root validation before it makes the release available to an instance.
Verified constraints
- A Windows junction can target a directory on a different local volume.
- A non-elevated process can create the tested junction without requiring Developer Mode.
Directory.GetDirectoriesandFile.Existsfollow the junction for the discovery operations used byModLibrary.AddModsandModEntry.Exists.- Removing a tested junction directly leaves its target directory and files unchanged.
- The current recursive instance deletion fails when a junction is below the instance root. Link-aware instance deletion is therefore part of this issue.
- Windows junctions do not support mapped network targets. A normal copy is the safe fallback when Borea cannot create the platform link.
Tests
- A real game launch discovers and loads a mod through the platform link.
- Windows creates and reads a junction on one local volume.
- Windows creates and reads a junction whose target is on another local volume.
- Linux and macOS create and read a directory symbolic link.
- Installing the same static release into another instance does not download or extract it again.
- Removing one instance link does not change the shared target or another instance link.
- Deleting an instance removes its links and the remaining instance directory without changing shared targets.
- A broken or missing link target produces a clear recoverable error.
- The shared release is removed only after the last reference is gone.
- A writable mod and an unsupported link location use a private copy.
- A write through one shared link is visible through another link, which documents why writable mods must opt out.
Open questions
- How a mod declares that its installation directory must be writable per instance.
- Whether the shared-store key needs the verified archive digest in addition to the mod id and version, so two different archives cannot occupy the same store path.
- Whether a Windows network location is unsupported for shared storage or always falls back to private copies.
Not in scope
- Adding a writable-mod field to the index.
- Adopting mods that were not installed through Borea. That remains #52.
Depends on
#6, implemented by #72.
- Dominant language
- C#
- Stars
- 29
- Forks
- 3
- Avg merge
- 17h 46m
- Merged PRs (30d)
- 284
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from KSAModding/Borea
-
area:app
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
KSAModding/Borea#1162 · 1 comment ·
Maintainers usually reply within 1 day
-
area:docs good first issue
Difficulty 1/5 Under an hour Newbie friendliness 62/100
KSAModding/Borea#933 · 1 comment ·
Maintainers usually reply within 1 day
-
An older Borea starts with default settings after a newer one added a keyPossibly taken @Maximilian-Nesslauer claimed this today. Openarea:storage bug
KSAModding/Borea#1168 · 1 assignee ·
Maintainers usually reply within 1 day
-
area:app
Difficulty 3/5 1-2 days Newbie friendliness 58/100
KSAModding/Borea#1163 · 1 reaction ·
Maintainers usually reply within 1 day
-
area:app documentation good first issue
Difficulty 4/5 3-5 days Newbie friendliness 44/100
KSAModding/Borea#1161 ·
Maintainers usually reply within 1 day
All issues in KSAModding/Borea
Similar issues
-
enhancement needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
microsoft/microsoft-ui-reactor#1460 ·
Maintainers usually reply within 1 day
-
t/bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
dotnet/maui#39950 · 1 reaction ·
Maintainers usually reply within 1 day
-
The server's default HttpClient fails on plain http and on HTTPS servers without HTTP/2Possibly taken @yasmoradi claimed this today. Openarea / templates
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
bitfoundation/bitplatform#14659 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
CommunityToolkit/Datasync#600 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
NimblePros/deviq-hugo#121 ·
Maintainers usually reply within 1 day