Capacity
This page covers EmakiStorage's capacity domain model: the capacity section of config.yml, the four capacity sources, the three-level stackLimit, and what happens to occupancy when capacity shrinks.
capacity
capacity:
base_slots: 45
max_slots: 1000
warn_entry_count: 5000
default_stack_limit: 100| Field | Type | Default | Description |
|---|---|---|---|
base_slots | int | 45 | Default open slot count (45 = 5 × 9, matching the gui.storage_rows default). |
max_slots | int | 1000 | Hard ceiling on total slots. 0 means unlimited. |
warn_entry_count | int | 5000 | Logs a console warning when the entry count exceeds this value. 0 disables the warning. |
default_stack_limit | long | 100 | Config-level per-slot ceiling. At this level 0 means unlimited. |
Four Capacity Sources
effectiveSlots is the sum of four independently persisted sources, then clamped:
effective = clamp(base_slots + permission tier + grantedSlots + purchasedSlots, 0, max_slots)The upper clamp is skipped when max_slots is 0. Because the four sources are stored separately, lowering base_slots never consumes slots a player was granted or purchased.
| Source | Comes from | Can be negative |
|---|---|---|
baseSlots | capacity.base_slots | No (negatives treated as 0) |
permissionSlots | Highest emakistorage.slots.<n> tier | No |
grantedSlots | /estorage slot grant, API grantSlots, action storage-grant-slot | Yes |
purchasedSlots | In-GUI paid expansion, action storage-unlock-slot | No |
Page count is derived from slot count and cannot be configured in reverse:
totalPages = max(1, ceil(effectiveSlots / slots per page))
reachablePages = max(1, ceil(usedSlots / slots per page))Page 1 is always reachable (an empty warehouse must still open and accept its first item); a page holding no entry at all cannot be paged into.
Confirm you have enough memory before setting max_slots to 0 (unlimited). The figure given in the config comment is roughly 100–200MB of heap for 100,000 entries on one player; that is an estimate and has not been measured.
Three-Level stackLimit
The per-slot ceiling resolves most-specific-first across three levels:
| Level | Stored in | Set through | Meaning of 0 |
|---|---|---|---|
| Entry | The matching entry in meta.yml | /estorage stacklimit slot, API setSlotStackLimit, action storage-set-stacklimit with slot | Inherit the player level |
| Player | defaultStackLimit in meta.yml | /estorage stacklimit player, API setStackLimit, action storage-set-stacklimit without slot | Inherit the config level |
| Config | capacity.default_stack_limit in config.yml | Config file | Unlimited (equivalent to Long.MAX_VALUE) |
The same 0 means different things per level: at entry and player level it means "inherit the next level", at config level it means "no limit". Resolution order is entry level > 0, then player level > 0, then the config level; a config level <= 0 yields Long.MAX_VALUE.
The emakistorage.stacklimit.<n> permission tier can also supply a player-level ceiling, again taking the highest value and not supporting wildcards.
Shrinking and Overflow
When a lowered capacity leaves occupancy beyond the boundary, the outcome is decided by unlock.overflow_policy. The key itself is documented in the unlock section of Configuration.
The Four overflow_policy Values
| Value | Behaviour |
|---|---|
lock_readonly | Entries beyond the capacity boundary become read-only: withdrawable, not depositable, released as soon as they are emptied. Recommended. |
compact | Overflowing entries roll forward into free slots. Entries are already stored in a gap-free compact list, so "roll forward" is the list's natural state; whatever still does not fit degrades to lock_readonly. |
return_inventory | Tries to hand overflowing entries back to the player's inventory; whatever does not fit degrades to lock_readonly. Nothing is returned while the player is offline, entries are simply locked. |
reject_change | Refuses the shrink outright. |
All four policies are zero-loss. There is deliberately no drop or delete: irreversible data loss must never be triggered implicitly by adjusting a config value.
Overflow state is not persisted. It is derived from capacity versus occupancy and recomputed whenever capacity changes — login, reload, permission change, command grant — so a stored flag can never drift out of sync with the facts.
Related Pages
- Configuration: the remaining
config.ymlsections such asunlock,behaviorandpersistence. - GUI and Display: how
gui.storage_rowsdecides the slots per page. - Unlock Costs: pricing and the purchase flow behind
purchasedSlots. - Commands and Permissions:
/estorage slot,/estorage stacklimitand the permission tiers. - API and Integration: how
StorageCapacityfields map onto configuration keys.