Asset store variant paths go over Windows' 260-character limit #15

Closed
opened 2026-10-07 07:15:17 +02:00 by kyuubi · 1 comment
Owner

Follow-up to #14. A storage folder should survive a copy between Linux and Windows, but variant files in the asset store can have paths too long for some Windows tools.

Variant files are stored as .assets/Variants/<signature>/<variant>, named with Resonite's variant identifier, e.g. version=3&compression=BC3nm_Crunched&quality=100&width=1024&height=1024&mips=False&filtering=Box&colorPreprocess=None&alphaPreprocess=None. In a real storage folder, 6,121 of 38,536 variant files exceed 260 characters under a root like C:\Users\someone\Documents\LocalStorage\; the longest is 238 characters relative to the storage root.

  • The mod is unaffected: .NET on Windows handles long paths.
  • Tools without long-path support can't copy them: Windows Explorer in many setups, and the built-in zip extractor. Robocopy, 7-Zip, rsync and Nextcloud copy them fine. Not tested on a Windows machine yet.
  • Items still load without them. PackageAssets.EnumerateVariants lists only the variant files present in the store, so a skipped file costs a slower first load.

Shortening the names changes the store layout, which tools/rebuild-package.py and the README's rebuild rule depend on, and existing stores would need converting.

Follow-up to #14. A storage folder should survive a copy between Linux and Windows, but variant files in the asset store can have paths too long for some Windows tools. Variant files are stored as `.assets/Variants/<signature>/<variant>`, named with Resonite's variant identifier, e.g. `version=3&compression=BC3nm_Crunched&quality=100&width=1024&height=1024&mips=False&filtering=Box&colorPreprocess=None&alphaPreprocess=None`. In a real storage folder, 6,121 of 38,536 variant files exceed 260 characters under a root like `C:\Users\someone\Documents\LocalStorage\`; the longest is 238 characters relative to the storage root. - The mod is unaffected: .NET on Windows handles long paths. - Tools without long-path support can't copy them: Windows Explorer in many setups, and the built-in zip extractor. Robocopy, 7-Zip, rsync and Nextcloud copy them fine. Not tested on a Windows machine yet. - Items still load without them. `PackageAssets.EnumerateVariants` lists only the variant files present in the store, so a skipped file costs a slower first load. Shortening the names changes the store layout, which `tools/rebuild-package.py` and the README's rebuild rule depend on, and existing stores would need converting.
Author
Owner

Fixed in 6e8fc3e, released as 0.7.17, deployed to MonkeyLoader/Mods.

Layout: Variants/<signature>/<id>, where <id> is the first 16 hex digits of the SHA-256 hash of the variant's full name, and VariantNames/<id> holds the full name. A name file only counts when its name hashes to its id. Name files are never swept, since sync can bring a variant file after its name. Full-name files from 0.7.16 and earlier are still read by the mod and by rebuild-package.py, and the first clean-up of a session renames them (renames only, so sync doesn't upload the variants again).

Verified:

  • Tests: 116 passed in Debug and Release, 1 skipped (the optional RLS_ROUNDTRIP_DIR round trip). Six new checks failed before the change.
  • A copy of the real store's variant names (empty files): 38,536 files in 9,429 folders renamed in 0.5 s, none failed. Every asset reads the same variant names afterwards, from disk. Longest store path 98 characters, 2,575 name files.
  • Twelve real items (593 MB, 710 variant files) copied with their store files in the old layout: C# and Python rebuilds are identical before and after the rename, and to each other.
  • Not checked in-game yet, and not on a Windows machine.
Fixed in 6e8fc3e, released as [0.7.17](https://forgejo.foxden.at/kyuubi/ResoLocalStorage/releases/tag/v0.7.17), deployed to MonkeyLoader/Mods. Layout: `Variants/<signature>/<id>`, where `<id>` is the first 16 hex digits of the SHA-256 hash of the variant's full name, and `VariantNames/<id>` holds the full name. A name file only counts when its name hashes to its id. Name files are never swept, since sync can bring a variant file after its name. Full-name files from 0.7.16 and earlier are still read by the mod and by `rebuild-package.py`, and the first clean-up of a session renames them (renames only, so sync doesn't upload the variants again). Verified: - Tests: 116 passed in Debug and Release, 1 skipped (the optional `RLS_ROUNDTRIP_DIR` round trip). Six new checks failed before the change. - A copy of the real store's variant names (empty files): 38,536 files in 9,429 folders renamed in 0.5 s, none failed. Every asset reads the same variant names afterwards, from disk. Longest store path 98 characters, 2,575 name files. - Twelve real items (593 MB, 710 variant files) copied with their store files in the old layout: C# and Python rebuilds are identical before and after the rename, and to each other. - Not checked in-game yet, and not on a Windows machine.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kyuubi/ResoLocalStorage#15
No description provided.