IceLemon Warehouse operational notes

Warehouse loads and saves use the synchronous WarehouseStore API on the Bukkit main thread. Opening or saving a warehouse can pause server ticks while the database responds. MySQL connection timeouts are bounded by the storage implementation; SQLite can also pause during disk or lock contention.

Warehouse items and the level are saved together in one database record. Upgrade vouchers live in the player's inventory and cannot participate in that database transaction. The plugin consumes vouchers before saving and restores the in-memory inventory and level if the save reports failure. A process or machine crash between the inventory change and committed database save can still leave the voucher consumed while the old level remains. Back up both player data and the warehouse database.

If a save fails, the current session remains loaded and dirty. Reopening that player's warehouse reuses the in-memory session rather than replacing it with a database load. A later close, page change, or shutdown retries the save.

Level 1 provides 27 slots, each subsequent level adds 9, and level 1000 provides 9018 slots across 201 pages. Persisted levels outside 1-1000 and malformed item data are rejected without overwriting the record. Changing max-level does not shrink existing warehouses.

Permissions: icelemonwarehouse.use and icelemonwarehouse.upgrade are granted by default. icelemonwarehouse.admin is operator-only. The highest explicitly granted icelemonwarehouse.maxlevel.N permission limits upgrades, bounded by configured max-level; without such permissions the configured maximum applies. Administrators use the configured maximum. LuckPerms works through standard Bukkit permission checks.

Voucher lore contains an HMAC-SHA256 signature bound to the recipient UUID and server secret. Name changes alone do not validate ordinary paper. Vouchers cannot be transferred to another player for redemption. Creative mode, administrators, and plugins capable of copying valid item metadata can copy signed vouchers; the signature is not a one-time redemption ledger.

Placeholders use cached immutable statistics, never Bukkit inventory access from the request thread. Statistics become available after the player's warehouse has loaded. Sessions remain in memory for the server lifetime; this deliberately retains unsaved data and avoids reload races, at the cost of memory proportional to players who have opened a warehouse.

Custom language files may be placed directly in the plugin data directory as <language>.yml. Missing keys fall back to the bundled English language. Reload applies languages and gameplay settings; storage configuration and voucher-secret changes require a restart. Back up voucher-secret with the database or existing vouchers will become invalid.

Serialization is bounded to 9018 item positions and 1 MiB of binary data. A warehouse with unusually large item metadata can exceed this limit; the plugin then refuses the save and retains its dirty session instead of truncating data. No automatic session eviction is performed. Placeholder permission limits are refreshed on warehouse interaction and reload, not directly when LuckPerms changes a permission.

Optimistic revision conflicts are retained as failed dirty sessions and never resolved by blindly overwriting another writer's record. Resolve conflicts operationally before retrying. Shutdown attempts outstanding saves but cannot guarantee durability if the database remains unavailable or the process terminates. The database and Minecraft player files cannot be committed atomically: crashes or uncertain database commit acknowledgements can cause item/voucher loss or duplication, including regular warehouse transfers. Use one warehouse writer per database and consistent backups.
