A shared store of static mod files, linked into instances

Open
#84 4 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
csharp
Domain
backend, desktop

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

area:core area:storage

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.GetDirectories and File.Exists follow the junction for the discovery operations used by ModLibrary.AddMods and ModEntry.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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from KSAModding/Borea

All issues in KSAModding/Borea

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.