Skip to content

Release 3.19.0#3012

Open
tastybento wants to merge 24 commits into
masterfrom
develop
Open

Release 3.19.0#3012
tastybento wants to merge 24 commits into
masterfrom
develop

Conversation

@tastybento

@tastybento tastybento commented Jul 6, 2026

Copy link
Copy Markdown
Member

Release 3.19.0

Highlights

Notes for server admins / addon developers

  • Build version is 3.19.0.

tastybento and others added 24 commits June 30, 2026 23:09
Picks up BentoBoxWorld/.github#11 — the publish prep step now reads the
release body from an env var instead of inlining it into the shell, so
backticks/$() in release notes no longer break the CurseForge/Hangar
publish (as happened on 3.18.1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0153KLwL66bB31pTc4BtsTMd
…-ca2dcd1

ci: bump pinned publish-platforms.yml to ca2dcd1
Add an optional second argument naming the island's current owner:

  /[gamemode] admin team setowner <newOwner> [islandOwner]

With the island named explicitly the command no longer needs the
executor to be standing on it, so it runs from the console (and thus
from automation such as Skript). Console execution also skips the
confirmation prompt, since the console cannot answer one. The single
argument, stand-on-the-island form is unchanged for in-game admins.

The named form targets the owner's primary/active island via
IslandsManager.getIsland(world, uuid). The concurrent-island cap and
old-owner demotion behaviour are unchanged.

- setOnlyPlayer(false); resolve island by owner name for the two-arg form
- skip confirmation when the sender is not a player
- new specify-island locale message for the console one-arg case
- tab-complete both name positions
- tests for the console/two-arg paths

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TpAfDgGQ5YyK8HKRXB2K88
- Two-arg form: require the named player to actually own the resolved
  island (island.getOwner()). getIsland() returns the active/primary
  island, which can be a team island they only belong to, so the old
  hasIsland() check could transfer the wrong island. Added a test.
- tabComplete: revert the args.size() gate. CompositeCommand passes the
  full args (including the team/setowner labels), so the gate returned
  no suggestions for the second parameter. Restore always suggesting
  online player names, which is correct for both name positions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TpAfDgGQ5YyK8HKRXB2K88
…friendly

Make admin team setowner console/automation friendly
- buildVersion is now 3.18.1 (was documented as 3.18.0)
- Fix managers list: remove non-existent IslandChunkDeletionManager;
  add the real IslandWorldManager, HousekeepingManager, ChunkPregenManager

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TpAfDgGQ5YyK8HKRXB2K88
Adds a protection flag that controls fishing with a fishing rod.
Casting and catching fish are checked at the hook's location, so
fishing into a protected area from outside is blocked too. Hooking
entities remains covered by the hurting and PVP flags.

The flag defaults to visitor rank so behavior on existing servers is
unchanged; game modes like Boxed can raise the rank to confine fishing
to island boundaries.

Fixes #1687

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DSNDntyLgy2861v5QckCVR
Adds the FISHING flag name/description/hint to all 22 non-English locale
files, preserving each file's existing style (including the MiniMessage
tags used in zh-CN and zh-HK). Also documents in CLAUDE.md that locale
translations are now produced with Claude rather than GitLocalize.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DSNDntyLgy2861v5QckCVR
Two changes from #1632:

Bug fix: players entering the end exit portal are now reliably returned
to their island instead of the server's global spawn. The handler keys
off PlayerRespawnEvent.RespawnReason.END_PORTAL rather than the
in-memory teleportOrigin map, which could be stale or empty (e.g. after
a relog inside the portal), and routes to the player's safe home via
the same resolution as ISLAND_RESPAWN, with a SafeSpotTeleport fallback.

Feature: valid bed and respawn anchor spawns are now honored under
ISLAND_RESPAWN and on end-portal return, provided the bed/anchor is on
an island the player is at least a member of in the same game mode.
This restores vanilla parity while still protecting against beds placed
while visiting other islands. A single new world setting,
BED_ANCHOR_RESPAWN (default enabled), lets admins disable it.

The home-safety resolution (home, one block above, quick island-center
offsets) moved from IslandRespawnListener into
IslandsManager#getSafeRespawnLocation so both respawn paths share it.

Locale entries for the new flag added to all 23 languages.

Fixes #1632

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DSNDntyLgy2861v5QckCVR
Item frames survived the blueprint copy since 3.2.6 (ItemFrameRec), but
the round trip was still broken:

- The facing direction of hanging entities was never stored, so pasted
  frames attached to an arbitrary face or popped off. Store BlockFace
  for any Hanging entity and re-apply it (forced) on paste.
- Paintings additionally lost their artwork. Store the Art registry key
  and restore it via Registry.ART with force=true.
- Fix a self-assignment bug in setFrame(): the stored isFixed value was
  never applied (frame.setFixed(frame.isFixed())).
- A hanging entity that cannot spawn (nothing to attach to) threw
  IllegalArgumentException out of spawnBlueprintEntity, silently
  dropping the remaining entities for that block. Catch it, log a
  warning, and continue.

Both new blueprint fields are nullable @expose additions, so existing
blueprints load unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLucPKxSBbG96WMVTFTuqB
Use getProtectedIslandAt instead of getIslandAt in keepVanillaSpawn so
bed/anchor spawns are only honored inside an island's protected area,
consistent with other location checks. Also remove useless eq()
matchers flagged by Sonar in the new tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DSNDntyLgy2861v5QckCVR
…in-blueprints

Fix #1752: Item frames and paintings in blueprints
…anics

Fix end exit portal respawn and honor bed/anchor spawns
Pasted paintings changed because of two issues:

- A painting entity's location is the center of its bounding box, which
  for even block widths/heights lies outside the anchor block Minecraft
  hangs the painting from (center is shifted half a block towards the
  counter-clockwise side of the facing, and half a block up). The
  blueprint stores the center's block, so respawning there shifted the
  anchor by one block and the painting no longer fit its original spot,
  popping or hanging displaced. The anchor is now recomputed from the
  art dimensions and facing before spawning.
- The art was applied only after the entity was already added to the
  world (spawnEntity picks a random largest-fitting variant). Paintings
  are now spawned via World#spawn with a pre-spawn consumer that forces
  the stored facing and art before the entity enters the world.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLucPKxSBbG96WMVTFTuqB
…in-blueprints

Paste paintings at their anchor block with art pre-applied (#1752 follow-up)
The STATUS, RANK filter and INVITE buttons in IslandTeamGUI hardcoded
their icons and ignored any icon: set in team_panel.yml, so server
admins could not change them (e.g. the rank filter to a HOPPER).

Add an applyIcon() helper that uses the template icon when present and
falls back to the previous hardcoded material otherwise. The status
button keeps the viewer's head as its default. Expose the icons in the
shipped team_panel.yml with explanatory comments so they are
discoverable.

Backwards compatible: installs with the shipped template keep the same
icons, and the fallback preserves behaviour when no icon is set.

Adds IslandTeamGUITest covering both the default and overridden icon.
The team_panel member_button and team_invite_panel prospect_button
templates referenced locale keys that did not exist and were never read
(commands.island.team.gui.buttons.member.{name,description} and
commands.island.team.invite.gui.buttons.member.{name,description}). The
button name and rank line were built entirely in code, so admins could
not customise them and the member rank was always shown with no override.

Wire the buttons to those keys:
- IslandTeamGUI.createMemberButton now sources the online member name
  from member.name ([name]/[display_name]) and the rank line from
  member.description ([rank]). Offline members keep their last-seen
  status (still customisable via the existing member-layout keys).
- IslandTeamInviteGUI.getProspect sources the prospect name from
  member.name and prepends an optional member.description line when set.

Defaults reproduce the previous output ([display_name], [rank], and an
empty prospect description), so this is backwards compatible. Added the
keys to en-US.yml and all bundled locales.

Adds IslandTeamGUIMemberTest and prospect name/description tests.
- copyPanelYaml now asserts the classpath fixture is present instead of
  silently doing nothing, so a missing resource fails fast.
- Change the STATUS button's commented icon example from PLAYER_HEAD to
  PAPER and note that a material replaces the viewer head with a plain,
  unowned icon (a template PLAYER_HEAD would be a generic head, not the
  viewer's).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLucPKxSBbG96WMVTFTuqB
- IslandTeamGUI.createMemberButton and IslandTeamInviteGUI.getProspect
  now fall back to the previous behaviour (display name / raw rank name /
  no extra lore line) when the new locale keys are absent, so an older or
  customised locale file that predates these keys does not render the raw
  key string in the GUI. A translateOr() helper encapsulates this.
- Use TextVariables.DISPLAY_NAME instead of the literal "[display_name]"
  (also fixes Sonar S1192).
- Remove unused anyString import in IslandTeamGUIMemberTest (Sonar S1128).
- Rework the tests to stub concrete locale values and assert the rendered
  output (verifying placeholder substitution), plus add fallback tests for
  the missing-key path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLucPKxSBbG96WMVTFTuqB
…gurable-icons

Make team_panel button icons configurable via the template (#3008)
…-description

Add customisable member/prospect name & description locale keys (#3009)
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant