🧪 Potion Stacking & Inventory Ergonomics (Minecraft 26.2)
📌 Repository Source Disclaimer: The documentation in this Wiki reflects the current source code state in the repository, which may include recent unreleased commits or developmental features ahead of public release builds on CurseForge and Modrinth.
1. Official Infobox
| Parameter | Technical Details |
|---|---|
| Subsystem Name | Potion Stacking & Inventory Ergonomics Engine |
| Implementation Class | PotionStackerManager.java (getModifiedStackSize) |
| Registration Interface | CustomStackSizeOverride (Stack Size Adjuster API) |
| Target Item Types | PotionItem (Regular, Splash, Lingering, Water Bottles) |
| Secondary Fallback Items | MUSHROOM_STEW, RABBIT_STEW, BEETROOT_SOUP, SUSPICIOUS_STEW |
| Controlling GameRule | potion-stacker-addon:potion_limit (Default: 16) |
| Secondary GameRule | potion-stacker-addon:stew_limit (Default: 16) |
| Upper Bound Limit | Integer.MAX_VALUE (2,147,483,647) |
| Recommended Safe Ceiling | 39,768,215 (prevents Large Chest 32-bit integer overflow) |
2. Step-by-Step Player Survival Workflow
Brewing Potions at the Brewing Stand: Place blaze powder into the fuel slot. Insert three water bottles or awkward potions into the bottom three brewing slots. When shift-clicking from a stack of bottles in your inventory, exactly 1 bottle enters each empty slot, while the rest remains stacked in your hand or inventory.
Collecting Brewed Potions: When brewing finishes, shift-click the finished potions into your inventory. Identical potions (matching effects, duration, and potency) automatically merge into single item stacks up to the active
potionLimit(default: 16).Drinking & Throwing Potions in Combat:
- Regular Potions: Drinking a stacked potion consumes 1 potion from the stack and immediately places an empty glass bottle into the player's inventory (or drops it if full).
- Splash & Lingering Potions: Right-clicking hurls 1 projectile and decrements the stack count by 1. Rapid throwing from hotbar is smooth and frictionless.
Inventory & Storage Management: Chest and barrel slots hold full stacks. A single standard Chest (27 slots) holding stacks of 16 stores 432 potions, compared to only 27 potions in vanilla Minecraft.
3. Mathematical Formulas & Storage Density
Storage Compression Multiplier ($C$)
The inventory compression ratio achieved relative to vanilla unstackable potions ($S_{\text{vanilla}} = 1$) is: $$C = \frac{S_{\text{limit}}}{S_{\text{vanilla}}} = S_{\text{limit}}$$
For default settings ($S_{\text{limit}} = 16$): $$C = 16\times \text{ more potions per inventory slot}$$
Container Storage Capacities
The total potion holding capacity for standard containers is given by: $$\text{Capacity}{\text{chest}} = 27 \times S{\text{limit}}$$ $$\text{Capacity}{\text{double_chest}} = 54 \times S{\text{limit}}$$ $$\text{Capacity}{\text{player_inventory}} = 36 \times S{\text{limit}}$$
| Container Type | Slots | Vanilla Capacity ($S=1$) | Modded Default ($S=16$) | Storage Gain |
|---|---|---|---|---|
| Player Hotbar | 9 | 9 potions | 144 potions | $+135$ potions |
| Main Inventory | 27 | 27 potions | 432 potions | $+405$ potions |
| Single Chest / Barrel | 27 | 27 potions | 432 potions | $+405$ potions |
| Large Double Chest | 54 | 54 potions | 864 potions | $+810$ potions |
| Shulker Box | 27 | 27 potions | 432 potions | $+405$ potions |
The 32-Bit Integer Safe Ceiling ($S_{\text{safe}}$)
Under the Player Agency & Anti-Nanny Invariant, players may configure stack limits up to $2{,}147{,}483{,}647$. However, to avoid exceeding the signed 32-bit integer ceiling across all 54 slots of a double chest: $$S_{\text{safe}} = \left\lfloor \frac{2^{31} - 1}{54} \right\rfloor = \left\lfloor \frac{2{,}147{,}483{,}647}{54} \right\rfloor = 39{,}768{,}215$$ Any value $\le 39{,}768{,}215$ guarantees that total container item counts cannot overflow JVM integer bounds.
4. Visual ASCII Diagrams & State Machine
Item Stacking Resolution Pipeline
[ Item Stack Size Query: getModifiedStackSize(item, original) ]
|
v
Is original <= 0?
/ \
YES NO
/ \
Return original Is item instanceof PotionItem?
/ \
YES NO
/ \
Return potionLimit Is item stew/soup?
(Default: 16) / \
YES NO
/ \
Is stew-stacker-addon loaded? Return -1
/ \ (Vanilla/fallback)
YES NO
/ \
Return -1 Return stewLimit
(Defer to sibling) (Default: 16)Brewing Stand Shift-Click Split Sequence
Player Inventory: [ Potion Stack (16x) ] --Shift-Click--> Brewing Stand GUI
|
+------------------------------------------------+
| |
v v
[ Slot 0: Empty? ] [ Slot 1: Empty? ]
/ \ / \
YES NO YES NO
/ \ / \
Insert 1x Check Slot 1 Insert 1x Check Slot 2
Stack: 15x Stack: 14x5. SNBT & Data Component Schemas
In modern Minecraft, potion effects and metadata are stored in data components (minecraft:potion_contents). Stacked potions share identical data components:
{
id: "minecraft:potion",
count: 16,
components: {
"minecraft:potion_contents": {
potion: "minecraft:strong_healing"
}
}
}When two potion item stacks encounter each other in an inventory, the Minecraft item handler compares their components. If identical, they merge up to potionLimit.
6. Exhaustive Reference Matrix
| Item Description | Minecraft Identifier | Vanilla Max | Potion Stacker Max | Controlling GameRule |
|---|---|---|---|---|
| Regular Potion | minecraft:potion | 1 | 16 (Configurable) | potion-stacker-addon:potion_limit |
| Splash Potion | minecraft:splash_potion | 1 | 16 (Configurable) | potion-stacker-addon:potion_limit |
| Lingering Potion | minecraft:lingering_potion | 1 | 16 (Configurable) | potion-stacker-addon:potion_limit |
| Water Bottle | minecraft:potion (water) | 1 | 16 (Configurable) | potion-stacker-addon:potion_limit |
| Mushroom Stew | minecraft:mushroom_stew | 1 | 16 (Configurable) | potion-stacker-addon:stew_limit |
| Rabbit Stew | minecraft:rabbit_stew | 1 | 16 (Configurable) | potion-stacker-addon:stew_limit |
| Beetroot Soup | minecraft:beetroot_soup | 1 | 16 (Configurable) | potion-stacker-addon:stew_limit |
| Suspicious Stew | minecraft:suspicious_stew | 1 | 16 (Configurable) | potion-stacker-addon:stew_limit |
7. Developer & Addon Extension Hooks
Resolution Method Implementation (PotionStackerManager.java):
public static int getModifiedStackSize(Item item, int original) {
if (original <= 0) {
return original;
}
if (item instanceof PotionItem) {
return potionLimit;
}
if (isStewOrSoup(item)) {
// Defer stew handling to stew-stacker-addon if loaded to prevent conflicts
if (FabricLoader.getInstance().isModLoaded("stew-stacker-addon")) {
return -1;
}
return stewLimit;
}
return -1;
}Registration with Stack Size Adjuster API (PotionStackerFabric.java):
net.instantgratification.stacksizeadjuster.util.StackSizeManager.registerOverride(
(net.instantgratification.stacksizeadjuster.util.CustomStackSizeOverride) (item, originalSize) ->
PotionStackerManager.getModifiedStackSize(item, originalSize)
);