Local Storage inventory backed by .resonitepackage files #1

Closed
opened 2026-09-25 08:20:14 +02:00 by kyuubi · 1 comment
Owner

MonkeyLoader mod that adds a Local Storage inventory, modelled on art0007i/LocalStorage, but every saved item is written as a self-contained .resonitepackage. A package carries the object graph, all its assets and the thumbnail, so it can be dragged into Resonite and spawned without the mod installed.

Design

  • Storage layout: inventory folders map to real folders under a configurable root (default <LocalDB permanent path>/LocalStorage). One item = one <name>.resonitepackage. Folder links are stored as <name>.link.json. Storage URIs use the resolocalstorage:/// scheme and owner id L-ResoLocalStorage, so the mod can sit next to art0007i's LocalStorage without clashing.
  • Save: RecordDirectory.AddItem for the local owner builds the package with the engine's own asset collection (PackageCreator logic) in the background and embeds the thumbnail as an extra package asset referenced by the main record's ThumbnailURI (packdb:///<sig>). Vanilla import ignores the extra asset.
  • Browse: RecordDirectory.LoadFrom lists folders, packages and links from disk; each package's main record supplies name/tags; its embedded thumbnail is imported into LocalDB once (deduped by signature) for display.
  • Spawn / equip: Slot.LoadObjectTask recognises resolocalstorage:/// package URIs and runs the vanilla PackageImporter, so spawning from the inventory behaves exactly like dropping the file into the world.
  • Delete: items and folders move to <root>/.trash/ instead of being erased.
  • Packages dropped into the storage folder by hand (e.g. vanilla exports) show up in the inventory too.

Plan

  • Project scaffold: Remora.Resonite.Sdk MonkeyLoader mod, config section (storage path, include variants)
  • Pure storage layer: inventory path ↔ filesystem mapping, name sanitising, unique file names, trash
  • Package layer: build package with embedded thumbnail, read main record + thumbnail
  • Unit tests for the storage and package layers
  • Inventory patches: Local Storage entry in the owner list, CanWrite, cache bypass, load/add/delete for items, folders and links
  • Spawn/equip patch via PackageImporter
  • Build + install the nupkg into the game's MonkeyLoader Mods folder
  • In-game check: save, browse, spawn, delete, and spawn a saved package without the mod

Known limits (v1)

  • Favouriting a local item (avatar, home, etc.) stores a resrec:/// URL that only this machine can resolve.
  • Saving world orbs to local storage is not supported.
MonkeyLoader mod that adds a **Local Storage** inventory, modelled on [art0007i/LocalStorage](https://github.com/art0007i/LocalStorage), but every saved item is written as a self-contained `.resonitepackage`. A package carries the object graph, all its assets and the thumbnail, so it can be dragged into Resonite and spawned without the mod installed. ## Design - **Storage layout:** inventory folders map to real folders under a configurable root (default `<LocalDB permanent path>/LocalStorage`). One item = one `<name>.resonitepackage`. Folder links are stored as `<name>.link.json`. Storage URIs use the `resolocalstorage:///` scheme and owner id `L-ResoLocalStorage`, so the mod can sit next to art0007i's LocalStorage without clashing. - **Save:** `RecordDirectory.AddItem` for the local owner builds the package with the engine's own asset collection (`PackageCreator` logic) in the background and embeds the thumbnail as an extra package asset referenced by the main record's `ThumbnailURI` (`packdb:///<sig>`). Vanilla import ignores the extra asset. - **Browse:** `RecordDirectory.LoadFrom` lists folders, packages and links from disk; each package's main record supplies name/tags; its embedded thumbnail is imported into LocalDB once (deduped by signature) for display. - **Spawn / equip:** `Slot.LoadObjectTask` recognises `resolocalstorage:///` package URIs and runs the vanilla `PackageImporter`, so spawning from the inventory behaves exactly like dropping the file into the world. - **Delete:** items and folders move to `<root>/.trash/` instead of being erased. - Packages dropped into the storage folder by hand (e.g. vanilla exports) show up in the inventory too. ## Plan - [x] Project scaffold: Remora.Resonite.Sdk MonkeyLoader mod, config section (storage path, include variants) - [x] Pure storage layer: inventory path ↔ filesystem mapping, name sanitising, unique file names, trash - [x] Package layer: build package with embedded thumbnail, read main record + thumbnail - [x] Unit tests for the storage and package layers - [x] Inventory patches: Local Storage entry in the owner list, `CanWrite`, cache bypass, load/add/delete for items, folders and links - [x] Spawn/equip patch via `PackageImporter` - [x] Build + install the nupkg into the game's MonkeyLoader `Mods` folder - [x] In-game check: save, browse, spawn, delete, and spawn a saved package without the mod ## Known limits (v1) - Favouriting a local item (avatar, home, etc.) stores a `resrec:///` URL that only this machine can resolve. - Saving world orbs to local storage is not supported.
Author
Owner

v0.1.0 builds and all 26 unit tests pass (storage layout + package read/write). Hot-loaded into the running game (Resonite 2026.9.18.82, MonkeyLoader 0.29 / Resonite gamepack 0.33): the mod loaded, OnEngineReady ran with no errors, and the storage folder is /home/kyuubi/Resonite_Data/data/LocalStorage. The in-game check of save, browse, spawn, delete and spawning without the mod is still open. Code is not committed yet.

v0.1.0 builds and all 26 unit tests pass (storage layout + package read/write). Hot-loaded into the running game (Resonite 2026.9.18.82, MonkeyLoader 0.29 / Resonite gamepack 0.33): the mod loaded, OnEngineReady ran with no errors, and the storage folder is `/home/kyuubi/Resonite_Data/data/LocalStorage`. The in-game check of save, browse, spawn, delete and spawning without the mod is still open. Code is not committed yet.
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#1
No description provided.