Capacity, Slots & Slot Masks

Capacity, Slots & Slot Masks

Lotus uses these types to describe where things live in a menu:

  • Capacity for the grid size
  • Slot for one position
  • SlotMask for many positions

Once these three click, the rest of the layout API becomes much easier to read.

All three are immutable values. They are safe to reuse, store in constants, and pass around freely.

Capacity

Capacity describes the menu grid in rows and columns.

Capacity chest3 = Capacity.ofRows(3);                // 3 x 9
Capacity chest6 = Capacity.ofRows(6);                // 6 x 9
Capacity hopper = Capacity.of(InventoryType.HOPPER); // 1 x 5
Capacity workbench = Capacity.of(InventoryType.WORKBENCH); // 2 x 5
Capacity custom = new Capacity(3, 3);               // any positive grid

When to use which factory

  • Use Capacity.ofRows(n) for normal chest menus.
  • Use Capacity.of(InventoryType.X) for fixed-layout inventories like HOPPER or DISPENSER.
  • Use new Capacity(rows, columns) when you need a custom grid.

Capacity.of(InventoryType.CHEST) gives you a 3-row chest, because InventoryType.CHEST does not encode whether you wanted 1, 2, 3, 4, 5, or 6 rows. For chest menus, prefer Capacity.ofRows(...).

Slot

A Slot is one cell in the inventory.

Capacity capacity = Capacity.ofRows(3);

Slot center = Slot.at(1, 4, capacity); // row 1, column 4 -> raw slot 13
Slot first = Slot.first();             // raw slot 0
Slot last = Slot.last(capacity);       // raw slot 26

int row = center.row(capacity);        // 1
int column = center.column(capacity);  // 4

Lotus uses zero-based rows and columns:

  • first row = 0
  • first column = 0

Slot.at(row, column, capacity) is the easiest way to stay readable while learning Lotus. You can always drop down to raw slot indices later if you want.

SlotMask

A SlotMask is a reusable description of multiple slots.

Capacity capacity = Capacity.ofRows(6);

SlotMask everything = SlotMask.full(capacity);
SlotMask middleBand = SlotMask.range(capacity, Slot.of(10), Slot.of(43));
SlotMask contentArea = SlotMask.full(capacity)
    .excluding(Slot.of(0), Slot.of(8), Slot.of(45), Slot.of(53));
SlotMask picks = SlotMask.of(capacity, Set.of(Slot.of(11), Slot.of(13), Slot.of(15)));

This becomes useful anywhere Lotus needs a phrase like "fill these slots" or "render page items into these slots".

When slot order matters, such as pagination fill order, prefer masks built from full(...).excluding(...) or range(...). They are clearer and more predictable than an arbitrary custom set.

Direction And Drawing

You will see Direction when using ContentBuilder.draw(...) and SlotIterator:

Direction.RIGHT
Direction.LEFT
Direction.DOWN
Direction.UP
Direction.DOWN_RIGHT
Direction.DOWN_LEFT
Direction.UP_RIGHT
Direction.UP_LEFT

That is the vocabulary Lotus uses for drawing horizontal, vertical, and diagonal lines in a menu.

The Big Picture

Capacity -> how large is the menu?
Slot -> where does one button go?
SlotMask -> where does a group of buttons go?

Next up: Content, the actual slot-to-button map inside a live menu view.