## 1.5.4
### Bug Fixes
- Fixed a ghost lockpick briefly appearing at the insertion depth when a pick broke at the far end of a long lock (netherite and other 13+ pin locks). `LockPickingScreen.updatePickParts()` did not clamp the right fragment's texture width, so on long locks the UV overflowed the pick atlas and the edge-clamped sample rendered as a full pick silhouette behind the breaking pieces. The right fragment now clips to the atlas and follows the pick's actual insertion position.
## 1.5.3
### Bug Fixes
- Fixed inability to place locks on containers in Adventure gamemode. Vanilla's `ItemStack.useOn()` short-circuits when `mayBuild` is false, which prevented `LockItem.useOn()` from ever firing. Lock placement now falls back to the `RightClickBlock` event handler when sneak-clicking with a lock item in Adventure mode, matching how picking, relocking, and pickup already worked.
## 1.5.2
### Bug Fixes
- Fixed keys, master keys, key rings, Awareness enchantment, and curio key rings being unable to re-lock unlocked lockables. The toggle logic only ran when at least one lockable was locked; unlocking all lockables at a position made re-locking impossible in all game modes.
- Fixed `NullPointerException` crash in `StructureTemplateMixin` when the lockable handler capability is missing during structure copy or paste operations.
- Fixed `Lock.fromBuf` creating an all-zero pin combo on the client instead of generating a proper dummy combo from the lock's ID seed.
- Fixed `KeyRingInventory.extractItem` using `getMaxStackSize()` instead of `getCount()` as the extraction limit, violating the `IItemHandler` contract.
- Fixed `Transform.fromDirectionAndFace` returning null for unmapped direction/face combinations, which could cause `NullPointerException` in lock state calculations. Now falls back to `NORTH_MID`.
- Fixed `LockItem.isOpen()` calling `getOrCreateTag()` on read, which unnecessarily created empty NBT tags on items without existing data.
### Loot-Scaled Lock Generation
- Chests whose loot value falls below all configured tier thresholds no longer receive a lock when loot-scaled locks are enabled. Previously, these low-value chests always received a wood lock despite the config description stating otherwise.
### New Config
- Added **Loot Table Injection Patterns** server config option. Controls which loot tables receive lock pick and key loot injection. Default: `minecraft:chests/`. Add entries like `some_mod:chests/` to inject into modded dungeon chests.
### Security
- Added additional server-side validation to lock picking packets: the server now re-checks that the lock is still locked and the player still holds a valid pick before processing each pin attempt.
### Misc
- Invalid entries in the `Lockable Tags` config list now log a warning instead of being silently skipped.
## 1.5.0
### Generation Chance
- Re-enabled the `Generation Chance` config setting. In 1.4.4 this was disabled and all generated chests received a lock unconditionally. It is now a functional setting again (default 1.0). Lowering it allows a percentage of generated chests to skip lock placement.
### Bug Fixes
- Fixed lock picking GUI showing garbled textures when a lockpick breaks. The broken pick halves were being rendered with the lock body texture atlas (48x80) instead of the lockpick texture atlas (160x16), causing completely wrong UV sampling.
- Fixed the left broken pick piece's fade animation targeting the wrong sprite (right piece instead of left piece).
- Fixed adjacent Lootr chests not all receiving locks. When two Lootr single chests were next to each other, Minecraft auto-connected them as a double chest (`LEFT`/`RIGHT`), and the `RIGHT` half was filtered out before lock placement could run.
## 1.4.8
### Security
- Lock pin combinations are no longer sent to clients over the network. The server now only transmits the pin count; pin validation remains fully server-authoritative. Previously, the full combo was readable from packets, trivially bypassing the lock picking minigame.
- Network version predicates now enforce strict version matching. Clients and servers with mismatched mod versions are cleanly rejected instead of silently connecting with incompatible packet formats.
- Server-to-client pin attempt packets are now range-validated, rejecting out-of-bounds pin indices.
### Bug Fixes
- Fixed locks failing to render on multiplayer clients when the server's `Max Lockable Volume` config exceeded the default value. Client-side packet handling no longer re-runs volume/intersection validation that only the server should perform.
- Fixed potential client crash (`NullPointerException`) when lock packets arrive during dimension transitions or disconnect, before the client level is initialized.
- Fixed potential server crash (`NullPointerException`) when removing a lockable whose bounding box spans a chunk that has already been unloaded. Unloaded chunks are now skipped gracefully.
- Fixed lock-close sound playing to nearby players even when lock placement fails server-side validation (e.g. overlapping an existing lock). Sound now plays only after successful placement.
- Fixed the key crafting recipe consuming all key blanks in the grid but producing only one key. The recipe now accepts exactly one blank per craft.
- Fixed worldgen lock placement only registering in the first chunk when a double chest spans a chunk boundary. All intersecting proto-chunks now receive the lockable.
- Fixed potential `ArrayIndexOutOfBoundsException` when loading lockables with corrupted or out-of-range transform data from NBT. Invalid indices now fall back to the default transform.
- Fixed lock picking GUI springs not animating when pins move (regression from 1.4.2 rendering migration).
### Textures
- Changed the Netherite Lock Pick texture.
- Fixed the unlocked Netherite Lock texture.
- Darkened the Netherite lock mechanism texture.
### Cleanup
- Removed dead code: unused `LocksCapabilities.registerCaps()`, `LocksConfig.canGen()`, `WrittenBookItem` import, and commented-out code blocks across `Lock`, `Cuboid6i`, `LockPickingContainer`, and `LocksClientUtil`.
## 1.4.4
### Guaranteed Lock Generation
- All generated chests with loot tables now receive a lock. Chests that previously fell below the lowest loot value threshold (or failed the 85% generation chance roll) now get a wooden lock instead of no lock at all.
- The `Generation Chance` config setting is no longer used — all generated chests are locked unconditionally. The setting is kept in the config file for backwards compatibility.
## 1.4.3
### Bug Fixes
- Fixed locked chest generation being restricted to overworld biomes. Structure chests can now generate locks in the nether, the end, and modded dimensions as well.
## 1.4.2
### Netherite Lock Pick
- Netherite lock picks now use durability instead of being consumed outright when a failed pin attempt triggers a break.
- Added **128 durability** to the Netherite Lock Pick.
- Netherite lock picks can now be repaired with **Netherite Ingots** in an anvil.
- Netherite lock picks can now receive **Mending**.
- **Netherite Lockpick Unbreakable** now prevents durability loss entirely instead of only preventing the item from being deleted.
### Bug Fixes
- Fixed loot-scaled lock generation causing massive startup logspam from sampled loot functions such as invalid `SetItemDamageFunction` rolls on non-damageable items.
- Fixed loot-scaled lock generation crashing some modpacks by invoking loot-table behavior that performed structure lookups, world generation, or block-state access during startup/off-thread precomputation.
- Reworked loot value calculation to estimate chest value directly from loot table JSON data instead of executing live loot generation.
- When a chest loot table cannot be estimated safely, lock generation now falls back to the old random weighted system instead of failing or crashing world load.
## 1.4.1
### Bug Fixes
- Fixed locks not generating on chests during initial world creation. The async loot value pre-computation introduced in v1.4.0 left the cache empty during spawn area generation, causing all chests to receive no locks. Now falls back to random weighted lock selection while pre-computation runs in the background.
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }