Limits#
Limits allows you to limit island blocks and entities in GameModes like BSkyBlock and AcidIsland.
This addon was made to help limit lag-inducing entities or blocks, e.g., hoppers. It can be used to limit regular blocks and entities but not all can be limited.
Created and maintained by tastybento.
Useful links
Installation#
- Place the Limits addon jar in the addons folder of the BentoBox plugin
- Restart the server
- The addon will create a data folder and inside the folder will be a config.yml
- Edit the config.yml how you want.
- Restart the server if you make a change
Commands#
There is a user command and an admin command called "limits". Admins can check the limits of a specific island owner. Both show a GUI panel with the limits and the current count.
Setup - Config.yml#
The config.yml has the following sections:
- blocklimits
- blocklimits-nether
- blocklimits-end
- blockgrouplimits (1.29.0+)
- blockgrouplimits-nether / blockgrouplimits-end (1.29.0+)
- worlds
- entitylimits
- entitylimits-nether
- entitylimits-end
- entitygrouplimits
It also has these top-level toggles (all added in 1.29.0 unless noted): apply-member-limit-perms, show-limit-messages, stacked-plants-count-as-one, and log-limits-on-join.
Per-dimension limits (1.28.2+)
As of 1.28.2, block counts, entity counts, limits, and offsets are tracked independently for the overworld, nether, and end. A single limit defined in blocklimits or entitylimits applies separately to each dimension — e.g. HOPPER: 10 allows 10 hoppers in the overworld, 10 in the nether, and 10 in the end (30 total across the island). Use the optional -nether / -end sections to override a single dimension.
On first load after upgrading, your existing single-dimension data is migrated automatically into the overworld slot. The on-disk format changes, so take a backup before upgrading and note that downgrading afterwards is not supported.
blocklimits#
This section lists the maximum number of blocks allowed for each block material. Do not use non-block materials because they will not work. The limits apply independently in every dimension (overworld, nether, end).
Growth and damage variants are normalised to their canonical block — BAMBOO_SAPLING counts as BAMBOO, and since 1.30.0 KELP_PLANT counts as KELP — so a variant name used as a limit key (e.g. KELP_PLANT or CHIPPED_ANVIL) configures the canonical block's limit.
blocklimits-nether / blocklimits-end#
Optional sections that override the blocklimits defaults for the nether or the end respectively. They are commented out in the default config; uncomment and add entries to set dimension-specific block limits.
worlds#
This section lists block limits for specific worlds. You must name the world specifically, e.g. AcidIsland_world and then list the materials and the limit. World-named limits override the dimension-default limit above for that specific world.
entitylimits#
This section lists the default entity limits within a player's island space (protected area and to island limit). A limit of 5 will allow up to 5 entities. Affects all types of creature spawning. Also includes entities like MINECARTS. As of 1.28.2, entity limits apply independently per dimension, so the nether and end are now counted and limited correctly (this fixes the long-standing bug where nether/end counts reset to zero on chunk unload).
entitylimits-nether / entitylimits-end#
Optional sections that override the entitylimits defaults for the nether or the end respectively. They are commented out in the default config; uncomment and add entries to set dimension-specific entity limits.
Note: Only the first 49 limited blocks and entities are shown in the limits GUI.
entitygrouplimits#
Experimental feature
The following feature is only available in development builds, which you may find on ci.codemc.io.
entitygrouplimits:
friendly:
limit: 2
entities:
- COW
- SHEEP
monsters:
limit: 4
entities:
- ZOMBIE
- CREEPER
blockgrouplimits#
Since 1.29.0
The block-side counterpart to entitygrouplimits: one shared limit across a set of block materials. The counts of every member are summed and checked against the group limit, so players can't dodge a limit by converting between related blocks (e.g. grass → dirt) or splitting across variants (piston / sticky piston). Individual blocklimits still apply on top if both are set.
Define a named group with an icon, a shared limit, and a materials list:
blockgrouplimits:
Pistons:
icon: PISTON
limit: 10
materials:
- PISTON
- STICKY_PISTON
Soil:
icon: GRASS_BLOCK
limit: 200
materials:
- GRASS_BLOCK
- DIRT
- DIRT_PATH
- FARMLAND
Per-environment overrides are supported via blockgrouplimits-nether / blockgrouplimits-end, which override only the numeric limit of a group already defined in blockgrouplimits:
blockgrouplimits-nether:
Pistons: 5
Run a recount after changing groups
After adding a block group (or changing stacked-plants-count-as-one below), run /[player_command] limits recount so stored counts match the new counting rules.
ItemsAdder & Oraxen custom blocks#
Since 1.29.0
Custom blocks from ItemsAdder and Oraxen can be limited using their ids directly in the existing blocklimits section (and its -nether/-end and worlds: overrides). Enforcement uses each plugin's own place/break events via BentoBox hooks, registered only when the plugin is installed. Quote keys containing a colon.
blocklimits:
"iafestivities:christmas/christmas_tree/green_orb": 5
"oraxen:caveblock": 10
Other toggles#
Description
(1.29.0+) When true, a team member's <gamemode>.island.limit.* permissions are merged into the island's limits when they log in — the highest value wins. Coop and trusted players are not team members and their permissions never apply.
Default: false
Description
(1.29.0+) When false, limits are enforced silently — placements and spawns are still blocked, but players receive no hit-limit message.
Default: true
Description
(1.29.0+) When true, a SUGAR_CANE, BAMBOO or KELP (kelp since 1.30.0) stalk counts as a single plant no matter how tall it grows — only the base segment is counted. Run a recount after changing this option.
Default: false
Description
Log an island's limits to the console when its owner joins. As of 1.29.0 this defaults to false (it previously defaulted to true) because it flooded the console on servers with many permission-based limits. Set it back to true if you relied on that output for debugging.
Default: false
Automatic entity recounts#
Since 1.30.2
Entity counts are maintained incrementally, so any missed event (sniffer egg hatches, mobs crossing portals, increments lost in a crash before the batched save) can leave them stuck away from reality with no way to recover except a manual recount. These options reconcile counts automatically in the background. They are off by default because a recount loads every chunk of the island's protection area: cost scales with the square of the protection range (64 chunks per world at range 50, 2,601 at range 400). Recounts are async, rate-limited to one island at a time, deduplicated and throttled per island, and only rewrite entity counts — block counts are left alone. A recount replaces counts rather than merging them, so it is only accurate when the island's chunks are loaded.
Description
Run a background entity-only recount of an island when its owner logs in.
Default: false
Description
Minimum seconds between automatic recounts of the same island (shared with the periodic sweep).
Default: 300
Description
Periodically sweep online islands to reconcile their entity counts, even while owners stay logged in. Same cost and caveats as recount-on-join.
Default: false
Description
Seconds between periodic sweep cycles.
Default: 300
Description
Islands to reconcile per sweep cycle. Keep small on high-population servers.
Default: 2
Description
Islands whose protection area covers more than this many chunks per world are never recounted automatically; a warning is logged once per island. 1000 chunks is a protection range of about 240. Manual recounts via the recount and calc commands are not affected.
Default: 1000
Permissions#
Island owners can have exclusive permissions that override the default or world settings. Two formats are supported:
-
GAME-MODE-NAME.island.limit.MATERIAL.LIMIT— applied to every dimension.example:
bskyblock.island.limit.hopper.10 -
GAME-MODE-NAME.island.limit.ENV.MATERIAL.LIMIT— applied to one dimension only, whereENVis one ofoverworld,nether, orend(1.28.2+).example:
bskyblock.island.limit.nether.hopper.5
Permissions activate when the player logs in.
Usage permissions are (put the gamemode name, e.g. acidisland at the front):
GAMEMODE_NAME.limits.player.limits:
description: Player can use limits command
default: true
GAMEMODE_NAME.mod.bypass:
description: Player can bypass limits
default: op
GAMEMODE_NAME.limits.admin.limits:
description: Player can use admin limits command
default: op
Full permissions are listed here.
Placeholders#
Tip
[gamemode] is a prefix that differs depending on the gamemode you are running.
The prefix is the lowercased name of the gamemode, i.e. if you are using BSkyBlock, the prefix is bskyblock.
Properly translated placeholders for each gamemode can be found:
Please read the main Placeholders page.
| Placeholder | Description | Limits version |
|---|---|---|
%Limits_[gamemode]_island_[material]_count% | Current count of material (lower cased) on the island | 1.17.2 |
%Limits_[gamemode]_island_[material]_limit% | The limit of material (lower cased) for the island | 1.17.2 |
%Limits_[gamemode]_island_[material]_base_limit% | The base limit of material (lower cased) for the island before permission-based increases | 1.19.1 |
%Limits_[gamemode]_island_[material]_[overworld|nether|end]_count% | Current count of material in that dimension only (the un-suffixed placeholder is the total across all dimensions) | 1.28.2 |
%Limits_[gamemode]_island_[material]_[overworld|nether|end]_limit% | The limit of material in that dimension only | 1.28.2 |
%Limits_[gamemode]_island_[material]_[overworld|nether|end]_base_limit% | The base limit of material in that dimension only | 1.28.2 |
%Limits_[gamemode]_island_reached_limits% | Comma-separated list of every limited block, entity, and entity group that is at or over its limit across all dimensions | 1.29.0 |
%Limits_[gamemode]_island_reached_limits_overworld% | Reached limits in the overworld only | 1.29.0 |
%Limits_[gamemode]_island_reached_limits_nether% | Reached limits in the nether only | 1.29.0 |
%Limits_[gamemode]_island_reached_limits_end% | Reached limits in the end only | 1.29.0 |
Block placeholder names
[material] is the lower-cased Minecraft key without the minecraft: namespace, e.g. %Limits_bskyblock_island_spawner_limit%. Custom blocks from ItemsAdder or Oraxen use namespace_key (for example itemsadder_ruby_block), since a colon is not valid in a placeholder name. Between 1.28.0 and 1.30.0 the block _count, _limit and _base_limit placeholders were mistakenly registered with the namespace baked in and did not resolve; fixed in 1.30.1.
Translations#
Help us keep translations accurate
Most BentoBox and addon translations are now generated with the help of AI, so the bulk of the work is already done — but AI is not perfect. What we really need from the community is error reports and corrections.
- Spotted a mistake or awkward phrasing? Open an issue or a PR on the relevant repository at bentobox.world (a short link to our GitHub org), or tell us on Discord.
- Want to add a brand-new language? Open a PR adding a new locale file to
src/main/resources/locales/in the relevant repo, or ask on Discord and we'll get you started.
| Language | Language code | Progress |
|---|---|---|
| English (United States) | en-US | 100% (Default) |
| Chinese, China | zh-CN | 98% |
| Chinese, Taiwan | zh-TW | 98% |
| Croatian | hr | 98% |
| Czech | cs | 98% |
| Dutch | nl | 98% |
| French | fr | 98% |
| German | de | 98% |
| Hungarian | hu | 98% |
| Indonesian | id | 98% |
| Italian | it | 98% |
| Japanese | ja | 98% |
| Korean | ko | 98% |
| Latvian | lv | 98% |
| Polish | pl | 98% |
| Portuguese | pt | 98% |
| Romanian | ro | 98% |
| Spanish | es | 98% |
| Turkish | tr | 98% |
| Ukrainian | uk | 98% |
| Vietnamese | vi | 98% |
Items that cannot be limited#
Some items cannot be limited (right now). The reasons are usually because there are too many ways to remove the item without it being tracked. If you are a programmer and can work out how to fix these, then please submit a PR!
- Primed TNT
- Evoker Fangs
- Llama Spit
- Dragon Fireball
- Area Effect Cloud
- Ender signal
- Small fireball
- Fireball
- Thrown Exp Bottle
- Shulker Bullet
- Wither Skull
- Tridents
- Arrows
- Spectral Arrows
- Snowballs
- Eggs
- Leashes
- Ender crystals
- Ender pearls
- Ender dragon
Item frames and paintings can now be limited (1.29.0)
Item frames, glow item frames, and paintings were previously on this list. Since 1.29.0 entity counting is persistent and event-driven, so all three can now be configured under entitylimits like any other entity.
For developers: exempting entities#
Coming in the next release after 1.30.2
Another plugin or addon can spawn entities that Limits ignores completely. This is useful for temporary mobs such as event waves or minigame NPCs that shouldn't use up an island's entity limits. Tag the entity with the persistent data key limits:exempt (any value) in the spawn consumer, so the tag is already there when CreatureSpawnEvent fires:
NamespacedKey limitsExempt = NamespacedKey.fromString("limits:exempt");
world.spawn(location, Zombie.class, zombie ->
zombie.getPersistentDataContainer().set(limitsExempt, PersistentDataType.BYTE, (byte) 1));
A tagged entity:
- is never blocked by an entity or group limit
- is never counted, so it doesn't use up the island's limit
- doesn't change any counts when it dies, is removed, or goes through a portal
- is skipped by recounts, both the
calccommand and automatic recounts
Untagged entities on the same island are limited as usual. The tag is saved with the entity, so the exemption survives chunk unloads and server restarts. You don't need Limits as a dependency; if you compile against it, Limits.EXEMPT_KEY is the same key.
Tag at spawn time only
Add the tag when the entity spawns and never add or remove it afterwards. An entity tagged later has already been counted and won't be decremented when it's removed, and removing the tag later causes the opposite problem. Either way the island's count is wrong until the next recount.
Changelog#
What's new in v1.30.2 — automatic entity recounts
Released: 2026-09-06
A piston-counting fix plus a new opt-in feature. Compatibility: BentoBox API 2.7.1 · Paper Minecraft 1.21.11 – 26.2 · Java 21.
- ⚙️ Automatic entity recounts (opt-in). New
recount-on-joinandrecount-periodicoptions reconcile drifting entity counts in the background — see Automatic entity recounts above. Six new keys (recount-on-join,recount-on-join-cooldown,recount-periodic,recount-periodic-interval,recount-periodic-batch,recount-max-chunks) are added toconfig.ymlautomatically with safe defaults, so nothing changes unless you enable them. Read the config comments before turning them on. Thanks @daniel-skopek. - 🐛 Extended pistons no longer count twice. The admin recount (
calc) counted both the base and the head of every extended piston, so a redstone build with all its pistons extended doubled the count (16 sticky pistons showing as 32/30) and every recalc put the wrong number back. The recount now counts only the base, and explosions that destroy both parts decrement once. - 🐛 Entities crossing portals off-island decrement correctly. An entity going through a portal while outside its island's protection range never had its source-dimension count decremented.
Piston note: islands whose piston count is inflated show the right number after one more recount (/[admin_command] limits calc <player>) on this version.
What's new in v1.30.1 — recount if you run Greenhouses
Released: 2026-09-04
Two accuracy fixes. Compatibility: BentoBox API 2.7.1 · Paper Minecraft 1.21.11 – 26.2 · Java 21. No config or locale changes.
- 🐛 Block count and limit placeholders work again. Since 1.28.0 every block placeholder was registered with the
minecraft:namespace baked into its name, so%Limits_bskyblock_island_spawner_limit%was really%Limits_bskyblock_island_minecraft:spawner_limit%and PlaceholderAPI returned it unparsed. All block_count,_limitand_base_limitplaceholders, including the_overworld,_netherand_endvariants, are now registered under the documented names. Entity placeholders were never affected. - 🔺 🐛 Entity counts no longer drift when a cancelled spawn is removed. When Limits cancelled a spawn at the limit and the spawning plugin then called
remove()on that never-added entity (Greenhouses did this), Paper still firedEntityRemoveEventand Limits decremented the count for a mob that was never counted, so the next spawn slipped through (e.g. 4/3 ghasts). Removals of entities that never entered the world are now ignored.
🔺 Recount note: if you run Greenhouses (or any plugin that removes entities it failed to spawn), entity counts on affected islands may have drifted low under previous versions. Run /[admin_command] limits calc <player> on affected islands, or have players run /[player_command] limits recount, so counts match reality.
What's new in v1.30.0 — kelp recount recommended
Released: 2026-08-15
Two counting-accuracy fixes. Compatibility: BentoBox API 2.7.1 · Paper Minecraft 1.21.11 – 26.2 · Java 21. No config or locale changes.
- 🐛 Bees can always leave their hives. A bee exiting a hive is not a new bee — its count was already subtracted when it entered — but the exit was still limit-checked. On an island at its bee limit the release was cancelled, the server retried every few ticks, nearby players were spammed with "Bee spawning limited to ..." and the stored bees were trapped forever. Hive exits are now exempt from the check while still being counted, so the enter/exit cycle stays net-zero. A placed hive item carrying never-counted bees can leave the island slightly over its limit; that simply blocks further spawns and breeding until the population drops.
- 🔺 🐛 Kelp columns count correctly. Kelp growth converts the
KELPtip into aKELP_PLANTstalk segment with no Bukkit event, so the old block was never decremented and kelp counts only ever grew, eventually blocking placement at phantom totals.KELP_PLANTis now normalised toKELP(likeBAMBOO_SAPLING/BAMBOO): growth is count-neutral, breaking the base of a column decrements every segment,KELPparticipates instacked-plants-count-as-one, and variant names such asKELP_PLANTorCHIPPED_ANVILused as limit keys configure the canonical limit.
🔺 If you limit kelp, run a recount. Stored kelp counts may have drifted upward under previous versions. Run /[admin_command] limits calc <player> on affected islands — or have players run /[player_command] limits recount — so counts match reality.
What's new in v1.29.1
Released: 2026-07-23
Compatibility: BentoBox API 2.7.1 · Paper Minecraft 1.21.11 – 26.2 · Java 21. No config or locale changes — this is a drop-in replacement.
- 🐛 Natural breeding now respects entity limits. Breeding that happens without a player involved (bees, foxes, villager-run breeders, and similar) bypassed the limit check entirely, so counts could grow past the configured limit. All breeding is now checked. Players with op or the bypass permission are still exempt.
- 🐛 Auto-breeders no longer retry every tick. When a breed attempt is refused at the limit, both parents are put on a breeding cooldown, and no hit-limit message is sent to nearby players unless a player actually fed the animals.
- 🐛 Player entries no longer leak into the entity tracking map. Players were being added to the entity-island tracking map and never removed.
- 🐛 Boats are now included in
recount. The admin recount counted minecarts but skipped boats, which zeroed boat counts that the live tracker could not then recover.
Thanks to @daniel-skopek for the fixes.
What's new in v1.29.0
Released: 2026-07-10
Compatibility: BentoBox API 2.7.1 · Paper Minecraft 1.21.11 – 26.2 · Java 21.
- ⚙️ Block group limits. One shared limit across a set of block materials (e.g. pistons + sticky pistons, or grass/dirt/farmland), so players can't dodge a limit by converting between related blocks. Configured under
blockgrouplimits, with-nether/-endoverrides. See the Configuration section above. - ⚙️ ItemsAdder & Oraxen custom block limits. Limit custom blocks straight from
blocklimitsusing their namespaced ids. - ⚙️ Team member limit permissions (opt-in). With
apply-member-limit-perms: true, team members'island.limit.*permissions can contribute to the island's limits, not just the owner's. - 🔡 Reached-limits placeholders & API. New
%Limits_<gamemode>_island_reached_limits%placeholders (plus_overworld/_nether/_end) list which limits are maxed, backed by a newLimits#getReachedLimits(...)API. Closes the oldest open ticket in the tracker (filed in 2018). - ⚙️ Stackable plants can count as one. Optionally count a whole sugar cane or bamboo stalk as a single plant (
stacked-plants-count-as-one). - ⚙️ Silent enforcement option.
show-limit-messages: falseturns off hit-limit chat messages while keeping limits enforced. - 🔡 Manual material/entity name translations. Locale files can now translate the block/entity names shown in the GUI and hit-limit messages.
- Item frames, glow item frames, and paintings can now be limited under
entitylimits. - 🐛 Fix: phantom entity counts from portaled mobs (e.g.
Chicken 10/10with no chickens on the island) and a copper golem build bypassing theCOPPER_CHESTlimit. - ⚙️
log-limits-on-joinnow defaults tofalse— set it back totrueif you relied on that console output.
New config options are not added automatically
New keys do not appear in an existing config.yml — add the ones you want from the list above, or delete the config to regenerate it. After adding a block group or changing stacked-plants-count-as-one, run a recount so stored counts match the new counting rules.
What's new in v1.28.4
Released: 2026-07-06
Maintenance release focused on keeping entity counts accurate and reliably persisted. No config or locale changes are required.
- 🐛 Entity counts no longer drift above reality. Under some spawn/removal sequences the tracked entity count could climb above the number of entities actually on the island, eventually blocking spawns that should have been allowed. Counts now stay in sync with the real island population. [#273]
- 🐛 Entity count persistence centralized. All entity count mutations now flow through
BlockLimitsListener, so changes are enrolled in the normal batch-save cycle instead of only being written on addon disable. This prevents count loss on an unclean shutdown or crash. [#274]
What's new in v1.28.3
Released: 2026-06-29
Bug-fix release — no data, config or locale changes; a drop-in replacement that makes per-island entity counts reliable across server restarts.
- 🐛 Entity counts no longer drift after a restart. The map linking each entity to its island was kept in memory only and lost on every restart. Entities reloaded from chunks never re-entered it, so when they later died or despawned off-island their count was never decremented and slowly crept upward. Entities are now re-registered as their chunks load, so off-island removals decrement correctly again.
- 🩹 No more map growth on chunk unload. The in-memory mapping is now released when a chunk unloads (and rebuilt on reload), preventing unbounded growth on long-running servers.
What's new in v1.28.0 — Java 21 required
Released: 2026-04-01
- Shulker duplication farms properly limited on Paper. Uses Paper's
ShulkerDuplicateEventto enforce limits before duplication occurs, fixing a bypass where shulkers teleported outside the island before the limit check. - Copper chest limits can no longer be bypassed. All copper chest variants (oxidized, waxed, scraped, golem-created) are now normalized to a single tracked material. Block state transitions are properly counted.
- Invalid config entries handled gracefully. Malformed namespaced keys, non-block materials, and uncountable materials (lava, water, air) in
blocklimitsconfig now produce clear warning messages instead of NPEs. - 🔺 Java 21 is now required (previously Java 17). Ensure your server runs Java 21 before upgrading.
- Bumped Spigot target to 1.21.11.
What's new in v1.28.1
Released: 2026-04-07
Hotfix for two regressions in 1.28.0:
- Existing databases load again. In 1.28.0 the
IslandBlockCountmap fields changed fromMap<Material, Integer>toMap<NamespacedKey, Integer>, breaking reads of pre-1.28.0 JSON files. A backwards-compatible GsonTypeAdapternow reads legacy enum names, namespaced strings, and the complex array form. No manual migration required — old files load as-is. - Block names in the limits GUI are readable again. Items were showing as
Minecraft:hopperdue to incorrect key formatting.
What's new in v1.28.2 — Per-dimension limits (data migration)
Released: 2026-06-13
- 🔺⚙️ Per-dimension limits. Block counts, entity counts, limits, and offsets are now tracked independently for the overworld, nether, and end, fixing the long-standing bug where nether/end counts reset to zero on chunk unload (#43). A single
blocklimits/entitylimitsvalue now applies to each dimension separately, with new optionalblocklimits-nether,blocklimits-end,entitylimits-nether, andentitylimits-endoverride sections. - 🔺 Data migration. Existing single-dimension data is migrated into the overworld slot on first load. The on-disk format changes, so take a backup before upgrading; downgrading afterwards is not supported.
- 🔺 Per-dimension permissions. A new 6-segment format,
<gamemode>.island.limit.<overworld|nether|end>.<KEY>.<NUMBER>, scopes a limit to a single dimension. The existing 5-segment format still applies to all dimensions. - 🐛 Accurate counting fixes: double-counted beds/doors (#86), golem/snowman block removal anchored on the pumpkin (#127), three entity-counting bugs, spawn eggs no longer consumed at the limit (#134), and count leaks during recount.
- 🩹 Resolves a
NoSuchFieldErrorcrash on Minecraft 1.21.8 and earlier caused by referencing 1.21.9 copper blocks; these are now resolved by name. - 🔡 All bundled locale files converted from legacy
&colour codes to MiniMessage, and missing keys synced across all 21 languages. Review any customised locale strings against the new files.
Compatibility: BentoBox API 2.7.1 · Minecraft 1.21.5 – 26.1.2 · Java 21.