Tags
Creators
Details
Licensed Apache-2.0
Published 8 months ago
Updated 2 months ago
All versions
1.2.0
Release
LightPlus 1.2.02 months ago 150
Uploaded by
Compatibility
Minecraft: Java Edition
26.3
26.2
26.1.x
1.21.x
Platforms
Folia
Paper
Purpur
Changes
[1.2.0] - 2026-08-31
Added
- Sound effects for light-block level switching, and all four LightPlus sounds (place, break, level change, level off) are now fully configurable under a new
soundssection inconfig.yml— each with its ownsoundkey,volumeandpitch, plus a mastersounds.enabledtoggle and per-sound muting via an emptysound. The level-change sound still slides its pitch up with brightness, now anchored to the configured pitch at level 15. - Land protection support. Placing, removing and adjusting light blocks now respects land/region protection plugins. Block break/place already flowed through standard Bukkit events; the interaction-driven paths (right-click level rotation, shift-right-click adjacent placement, left-click removal) now dispatch a simulated block break/place event and abort if a protection plugin cancels it. Works with WorldGuard, GriefPrevention, GriefDefender, Residence, Towny, Lands, PlotSquared, BentoBox (and its skyblock forks), and any other plugin that cancels
BlockBreakEvent/BlockPlaceEvent. Toggle it under the newland_protection.enabledoption (defaulttrue). Added the corresponding plugins tosoftdepend. /lightplus give <player> [level] [amount](permissionlightplus.give, default op) to hand a player leveled light items — level 0-15 (default 15), amount 1-64 (default 1) — with tab completion for the sub-command, player names and common values.- Per-player and per-world light-level caps. The highest
lightplus.maxlevel.<0-15>permission node a player holds is the brightest level they may set (right-click adjust, shift-place, and placing a stored-level item all clamp to it); players with no node fall back tolimits.default_max_level.limits.world_max_levels.<world>caps a level per world, and the effective limit is the lower of the two.lightplus.maxlevel.bypass(default op) removes all caps./lightplus giveis not clamped. actionssection inconfig.ymlto individually disable the extra interactions:adjust_level(right-click level cycle),place_adjacent(shift-right-click place),left_click_break(left-click removal), andpick_block. A disabled action falls back to vanilla behaviour.- Pick-block support: middle-clicking a placed light block in Creative gives a light item at that block's exact level (vanilla would give the default level).
actions.pick_block, on by default. - Sneak + scroll to step a placed light block's level up/down one at a time (looking at it, holding a light item). Unlike right-click it clamps at 0 and the player's max instead of wrapping.
actions.scroll_level, on by default. - Configurable
messages.prefix— a MiniMessage snippet (aLightPlus »gradient tag by default) prepended automatically to every chat message. Use the%prefix%token to place it manually or add it to an action-bar line. - Per-language messages. With
messages.follow_client_locale(on by default), each player gets the string frommessages.locales.<their client language>when one exists (keyed by full locale likezh_twor just the languagezh), otherwise the English default. Console always gets the default. Ships example Traditional Chinese (zh_tw) entries. /lightplus help(also shown with no arguments) — a formatted, gradient-headed command panel with click-to-type and hover text, listing only the sub-commands the sender can use./lightplus version— a panel showing plugin version, author, server/Minecraft version, Folia support, detected land-protection plugins, and metrics backends.MessageService.sendLinesfor multi-line MiniMessage output that keeps click/hover interactivity (sendsComponents instead of legacy strings).- Named light items. The
itemconfig section gives crafted / dropped / given light items a MiniMessage display name (%level%token) and lore;item.custom_name: falserestores the plain vanilla item. Different-level items already didn't stack; the name just makes the level readable. - Modrinth update check. On startup LightPlus asks the Modrinth API (off-thread, never blocking startup) for the latest release and compares it three ways: up to date, an update is available (logged +
lightplus.updatejoin notice), or the running build is ahead of the latest release (/lightplus versionshows "dev build"). Configured underupdate_check(enabled,notify_on_join); the project id is hard-coded. Message keymessages.update_available(%current%/%latest%/%url%). - Optional light-block decay (
decayconfig section, off by default). When on, a player-placed light block is removeddecay.after_secondslater; a repeating sweep clears expired blocks on their region thread. Pending lights are persisted todecay-data.yml(decay.persist, default on) — saved on shutdown and every ~60s, reloaded shortly after start — so they still decay across a restart.lightplus.decay.exempt(default op) places permanent lights; breaking a light by hand cancels its pending decay. - PlaceholderAPI expansion (identifier
lightplus, registered only when PlaceholderAPI is installed):%lightplus_version%,%lightplus_lights_placed%,%lightplus_lights_mined%,%lightplus_update_available%,%lightplus_latest_version%,%lightplus_pending_decay%, and the player placeholders%lightplus_max_level%,%lightplus_holding_light%,%lightplus_held_level%. - WorldGuard
lightplus-useregion flag (StateFlag, default allow). Setting it todenyin a region blocks every LightPlus light-block action there — adjust, place, shift-place and both break paths — regardless of build permission, and independently of theland_protection.enabledtoggle. Registered inonLoad; requires the flag registry, so it needs a server restart to take effect (not/reload). The WorldGuard API is aprovideddependency (EngineHub repo) and is not shaded.
Changed
- Added a
README.md(build / test / run-server docs) and a JUnit 5 test suite —mvn test, also run bymvn package— covering the update-check version comparison and light-level clamping. - Metrics initialisation (bStats + FastStats) is wrapped so a metrics failure logs a warning instead of aborting plugin enable.
- Rewrote
config.ymlcomments to explain the reasoning behind every option (how the land-protection check works, whatvolumeabove 1.0 does, pitch ranges, recipe shape rules, level-cap resolution, message tokens). - Sound settings, land protection, action toggles and level limits are read live, so
/lightplus reloadapplies them without a restart. - Expanded
plugin.ymlcommand and permission descriptions. - The
/lightpluscommand no longer carries a blanketlightplus.reloadrequirement; each sub-command checks its own permission, solightplus.givecan be granted independently.
Fixed
- MiniMessage messages containing a
<gradient:#hex:#hex>(such as the new prefix) rendered as literal<gradient::>text — the legacy&#RRGGBBconverter was rewriting the hex colours inside the tag. It now only rewrites hex when prefixed with&. registerCraftLightRecipecould throw and abort plugin enable when an upgradedconfig.ymlpredated thecrafting_recipesection (the shape resolved from jar defaults whileitemsdid not, producing an unmapped-symbol recipe). Recipe building is now validated up front — row count/length, single-character keys, valid materials, and every shape symbol having anitemsentry — and wrapped so any failure logs a warning and skips the recipe instead of disabling the plugin.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:VxJJsDNf:WAmQJh40"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:VxJJsDNf:WAmQJh40"
}

