Class CreatedSlot

java.lang.Object
net.minecraft.world.inventory.Slot
com.trevlar.slotkit.api.slot.CreatedSlot

public class CreatedSlot extends net.minecraft.world.inventory.Slot
A slot that is a vanilla Slot to everything outside it. It keeps its place in the hierarchy (panel, group, index) in final fields and belongs to a CreatedSlotGroup.

It behaves like a vanilla slot. Every override calls super, so vanilla's behavior and other mods' mixins still apply. It is also presented like one: its position is vanilla's own Slot.x/y, vanilla's slot pass draws it, and vanilla's getHoveredSlot finds it (see ContainerScreenLayers in MenuKit). A third party's extractSlot mixin, or any code that walks menu.slots and reads x/y, treats a created slot and a vanilla slot the same because they go through the same calls. The overrides:

  • mayPlace: false when inert; in a SHULKER_STORAGE group, false for an item that can't go inside a container item, as vanilla's ShulkerBoxSlot; otherwise super
  • mayPickup: false when inert, otherwise super
  • getItem: EMPTY when inert, otherwise super
  • isActive: false when the panel is hidden, otherwise super

Each group is its own container

Every slot group on a menu has its own Container, stable for the menu's life: all of a group's slots share it, no two groups share one (even over the same storage), and none is shared with the menu's own slots. Vanilla and other mods that tell containers apart by slot.container (sorting, shift-click, move-all) treat each group as its own container. A menu's own shift-click routing stops before every slot SlotKit appended, so a group takes a shift-click only through its own route. SlotGroupCategories.groups(menu) is the public way to ask which group a slot is in. Since 2.1.0.

A mod that mixes into Slot.mayPlace to add a global filter sees its filter run on created slots through the super.mayPlace call, and the most restrictive answer wins. A mod iterating slots sees inert created slots as empty, which is a valid state for any slot.

Hierarchy: Screen, then Panel, then CreatedSlotGroup, then CreatedSlot.

  • Field Summary

    Fields inherited from class net.minecraft.world.inventory.Slot

    container, index, x, y
  • Constructor Summary

    Constructors
    Constructor
    Description
    CreatedSlot(net.minecraft.world.Container container, int containerIndex, int x, int y, CreatedSlotGroup group, MenuPanel panel, String groupId, int localIndex)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Library use: ties the slot to its group's active count.
    This slot's created Address, the same in every menu.
    The CreatedSlotGroup this slot belongs to.
    net.minecraft.world.item.ItemStack
    Returns the item in this slot, or ItemStack.EMPTY when the panel is inert, so a hidden panel's storage is never exposed.
    int
    Index within the group (0-based).
    net.minecraft.resources.Identifier
    The group's SlotSpec.emptyIcon outline when declared, drawn by vanilla on an empty slot.
    Group this slot belongs to within its panel.
    void
    Library use: the panel is always shown on the server, and hidden only by the client's reveal.
    boolean
    Whether this slot is active (visible and usable).
    boolean
    True when this slot's panel is hidden, or the slot is past its group's active count.
    boolean
    mayPickup(net.minecraft.world.entity.player.Player player)
    Whether items can be taken.
    boolean
    mayPlace(net.minecraft.world.item.ItemStack stack)
    Whether this stack can be placed here.
    static @Nullable CreatedSlot
    of(net.minecraft.world.inventory.Slot slot)
    The created slot slot is, or null for any other slot.
    Panel this slot belongs to.
    void
    set(net.minecraft.world.item.ItemStack stack)
    Writes the stack, unless the slot is inert on both sides.

    Methods inherited from class net.minecraft.world.inventory.Slot

    allowModification, checkTakeAchievements, getContainerSlot, getMaxStackSize, getMaxStackSize, hasItem, isFake, isHighlightable, onQuickCraft, onQuickCraft, onSwapCraft, onTake, remove, safeClone, safeInsert, safeInsert, safeTake, setByPlayer, setByPlayer, setChanged, tryRemove

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • CreatedSlot

      public CreatedSlot(net.minecraft.world.Container container, int containerIndex, int x, int y, CreatedSlotGroup group, MenuPanel panel, String groupId, int localIndex)
      Parameters:
      container - vanilla Container adapter (from handler construction)
      containerIndex - index within the container
      x - screen x position
      y - screen y position
      group - owning CreatedSlotGroup
      panel - owning panel as the menu knows it (its visibility decides inertness)
      groupId - group identifier within the panel
      localIndex - slot index within the group (0-based)
  • Method Details

    • getNoItemIcon

      public net.minecraft.resources.Identifier getNoItemIcon()
      The group's SlotSpec.emptyIcon outline when declared, drawn by vanilla on an empty slot.
      Overrides:
      getNoItemIcon in class net.minecraft.world.inventory.Slot
    • of

      public static @Nullable CreatedSlot of(net.minecraft.world.inventory.Slot slot)
      The created slot slot is, or null for any other slot. Sees through creative's slot wrapper, so it works for a slot taken from any screen's menu.
    • panelId

      public String panelId()
      Panel this slot belongs to.
    • groupId

      public String groupId()
      Group this slot belongs to within its panel.
    • getLocalIndex

      public int getLocalIndex()
      Index within the group (0-based).
    • getGroup

      public CreatedSlotGroup getGroup()
      The CreatedSlotGroup this slot belongs to.
    • address

      public Address address()
      This slot's created Address, the same in every menu. Behavior is resolved by it.
    • isInert

      public boolean isInert()
      True when this slot's panel is hidden, or the slot is past its group's active count. To the outside world an inert slot looks like no slot at all: getItem returns EMPTY, mayPlace returns false, and shift-click skips it. set does nothing, unless only this client's reveal hides the slot (see set(ItemStack)).

      Public for third parties that want to check directly rather than rely on those methods.

    • activeCount

      @Internal public void activeCount(IntSupplier count)
      Library use: ties the slot to its group's active count.
    • hiddenOnlyOnClient

      @Internal public void hiddenOnlyOnClient()
      Library use: the panel is always shown on the server, and hidden only by the client's reveal.
    • mayPlace

      public boolean mayPlace(net.minecraft.world.item.ItemStack stack)
      Whether this stack can be placed here. An inert slot refuses. Otherwise this is vanilla's own answer, which SlotKit's slot gate (SKSlotGateMixin) has already checked against this slot's address. Calls super, so a mixin on Slot.mayPlace still runs.

      A SHULKER_STORAGE group holds a shulker box's contents, so it keeps vanilla's ShulkerBoxSlot rule: nothing that can't go inside a container item (a shulker box). Clicks, number keys, drags and shift-clicks all ask here.

      Overrides:
      mayPlace in class net.minecraft.world.inventory.Slot
    • mayPickup

      public boolean mayPickup(net.minecraft.world.entity.player.Player player)
      Whether items can be taken. Inert refuses; the slot gate and Curse of Binding are checked in SlotKit's mixin.
      Overrides:
      mayPickup in class net.minecraft.world.inventory.Slot
    • getItem

      public net.minecraft.world.item.ItemStack getItem()
      Returns the item in this slot, or ItemStack.EMPTY when the panel is inert, so a hidden panel's storage is never exposed.

      isActive(), mayPlace(ItemStack) and mayPickup(Player) returning false block interaction but not reading. Without this override, anything that reads slot.getItem() on a hidden slot (vanilla's broadcastChanges syncing to the client, other mods' mixins on Slot.getItem, consumer code walking menu.slots) would see the real contents. That would leak per-player state kept in hidden-panel storage (lock state, private inventories, sort state) to the client and to any mod hook.

      Returning EMPTY while inert prevents that. When the panel becomes visible, broadcastChanges sees the change and sends the real contents to the client. The backing Storage still holds the real items, and consumer code that owns the panel can read it directly.

      Inert means hidden from the world for both interaction and reading. Both are needed for the library's inertness guarantee, which SlotKit's validator tests.

      Overrides:
      getItem in class net.minecraft.world.inventory.Slot
    • set

      public void set(net.minecraft.world.item.ItemStack stack)
      Writes the stack, unless the slot is inert on both sides. A slot inert on both sides reads as EMPTY there, so a write to it is the world catching up with that EMPTY (the server syncing it to the client, a creative client sending it back), not a real change. Taking it would wipe the items the slot's storage still holds.

      A slot hidden only by this client's reveal is different: the server shows it and syncs its real contents, so the client keeps them, and they're there the moment the slot is revealed (and for anything reading the storage meanwhile, a HUD). It still reads as EMPTY while hidden. The server never resends what it already sent, so dropping the write would leave the client empty for good. Creative's echo of that EMPTY back to the server is stopped on the client (SKCreativeHiddenSlotMixin).

      Overrides:
      set in class net.minecraft.world.inventory.Slot
    • isActive

      public boolean isActive()
      Whether this slot is active (visible and usable).

      When false, vanilla skips the slot for rendering and hover detection. Together with getItem() returning EMPTY while inert, this hides the slot from the world entirely.

      Overrides:
      isActive in class net.minecraft.world.inventory.Slot