A lightweight, generalized library for representing inventories in any game and running operations on top of that data.
You can represent inventory data using types such as:
Map<Int, MyGameItem>List<MyGameItem>MyGameInventory
and perform operations like: give, take, has, ...
Gradle:
dependencies {
// Java
implementation("io.typst:inventory-bukkit:$THE_LATEST")
// Kotlin
implementation("io.typst:inventory-bukkit-kotlin:$THE_LATEST")
}Maven:
<dependencies>
<dependency>
<groupId>io.typst</groupId>
<artifactId>inventory-bukkit</artifactId>
<version>$THE_LATEST</version>
</dependency>
</dependencies>dependencies {
implementation("io.typst:inventory-core:$THE_LATEST")
}Prerequisite: io.typst:inventory-bukkit dependency.
Example 1: Put an item only into a specific slot (3), drop the rest items on the ground
// Using inventory-bukkit (Java)
BukkitInventories.from(inventory)
.withSubInventory(3) // can select a specific slot range
.giveItemOrDrop(player, item);// Using inventory-bukkit (Kotlin)
inventory.toMutator()
.withSubInventory(3) // can select a specific slot range
.giveItemOrDrop(player, item)Example 2: Only insert if there is enough space
if (BukkitInventories.from(inventory).giveItems(item)) {
// Success: inventory updated
} else {
// Failed: not enough space, inventory unchanged
}Example 3: Inventory represented as List or Map
// map: Map<Int, ItemStack>
BukkitInventories.from(map).giveItemOrDrop(player, item);
if (BukkitInventories.from(map).takeItems(items)) {
// success
}Example 4: Atomic operation -- take and give
// inventory: Inventory
// inputItem: ItemStack
// outputItem: ItemStack
// inputSlots: List<Int>
// outputSlot: Int
var mutator BukkitInventories.from(inv).copy(); // Copy
if (mutator.takeItems(inputItem) && mutator.giveItems(outputItem)) {
mutator.forEach(inv::set); // Update
// some another operations...
}BukkitInventoriesBukkitItemStacks
InventoryExtensionsItemStackExtensions
inventory is built around three main roles:
-
Item abstraction (
ItemStackOps<A>) Defines how to represent “empty”, compare, copy, and create items of typeA. -
Inventory view (
InventoryAdapter<A>) Adapts any storage structure into aslot -> itemview. -
Pure operations (
InventorySnapshotView<A>) Computes results such as modified slots and remaining quantities without directly mutating the underlying inventory.
By composing these three pieces, you can implement inventory logic not only for Minecraft inventories, but for any game.
- Wrap your inventory data with
InventoryAdapter<A>. - Implement
ItemStackOps<A>for your item type. - Create an
InventorySnapshotView<A>snapshot. - Call operations like
give/take/has. - Apply the resulting
modifiedItemsback to your game’s inventory state.
Applies pure operation results to the actual game inventory.
-
Reads results from
InventorySnapshotView:- Writes changes to slots
- Handles side effects such as dropping leftover items near an entity
-
Provides IO helpers for common
give/takepatterns
This cleanly separates calculation from effects, e.g.:
giveItemOrDrop(Entity, Item)takeItems(Item...): Boolean
A pure operation layer that does not directly modify the real inventory:
giveItems(A): InventoryPatch<A>takeItems(A...): InventoryPatch<A>hasItems(A): BooleancountItems(ItemKey)findSpaces(A): Map<Int, Int>findSlots(A): Map<Int, Int>- ...
Expressions:
- empty: InventorySnapshotView.empty(ItemStackOps, ItemKey)
Explicit representations of operation results.
- InventoryPatch
modifiedItems: slots to overwrite in the game inventoryfailure: failure resultgiveLeftoverItems: any part of the item that could not be insertedtakeRemainingItems: any part of the item that could not be taken
Expressions:
- empty: initial patch
- failure: InventoryPatch.failure(A)
Generalized interface for slot-based access, with implementations such as:
ListInventoryAdapter<A>: list-based inventoriesMapInventoryAdapter<A>: map-based inventoriesBukkitInventoryAdapter<A>: BukkitInventorySubInventoryAdapter<A>: a sliced view of anInventoryAdapter<A>over specific slots
Common operations for an item type:
empty(): A: representation of an empty itemisEmpty(A): Boolean: whether the item is emptyisSimilar(A, A): Boolean: whether two items are similar/stackablegetAmount(A): Int/setAmount(A, Int): read/write item amountgetMaxStackSize(A): Int: maximum stack sizecopy(A): A: copy an item