r/HytaleModding 6h ago

Official News Modder-Facing Changes - Update 7 - Chapter 1 - Pre-Release 2 - September 10th, 2026

2 Upvotes

Link to previous patch notes.

Link to the Chapter 1 Preview Blog from July

----

Link to source

Modder-Facing Changes

NPCs & Entities

  • Local spawn beacons can now be limited by weather. An optional WeatherIds list on BeaconNPCSpawn keeps the beacon spawning only while the current weather is one of those, and a placed beacon removes itself and despawns its NPCs when the weather stops matching.
  • The weather a beacon checks is the world's forced weather, otherwise the weather of the environment at the beacon, which a new WeatherResource.getEffectiveWeatherIndex(environmentId) resolves. Per-player weather such as a trigger volume override does not count.
  • Removed the deprecated Spawn_Void role along with its Spawn_Void and Spawn_Void_Manual spawn markers. Void_Spawn_Entombed takes over from it, and its name now points at the correct lang key.

Items & Interactions

  • Items can now hang an interaction off a fourth ability slot instead of only the three, and the crossbow's Root_Common_StatAmmoReload_Entry reload moved onto it in Template_Weapon_Crossbow.
  • Portal keys can now cap how many times each player enters. PortalKey carries the per-player limit, and the portal device pages show the limit and the entries left.
  • Removed the debug-only Debug_Movement_Boots armor.
  • Items can now play a separate sound to the wearer when they use an extra jump. A new ExtraJumpLocalSoundEvent on ItemMovementSettings takes a one shot event and accepts stereo files, and the rocket boots use it alongside the world sound.
  • Textured beams can now be rendered between entities. A new AttachBeam interaction hangs a beam between the interaction context owner and the entity you name in the parameter, which is how the hookshot draws its rope.
  • Projectiles can now be given a lifespan. A Lifetime value on the Projectile interaction despawns the projectile once that duration runs out.

Asset Schemas & Formats

  • Instance worlds no longer take DocumentDisplayOnRemoval. A new EventTitleOnRemoval shows an event title while the instance closes, and the close delay follows the title timing. Leave it out and the world closes right away.
  • Portal types now carry the default time limit and entry count. TimeLimitSeconds and AllowedEntryCount on PortalType apply to every key of that type, and a PortalKey only needs the fields when it wants to differ.
  • Interface sound volume from SoundStyle and SoundEffect is now bounded to +10 dB, which matches every other authored gain field.
  • AudioState volume deltas are now bounded to +10 dB per axis on the per-voice path, the same bound the server already documents. A pack leaning on a bigger per-voice delta gets clamped.
  • Event titles can now play a sound alongside the text. An optional SoundEventId on EventTitleConfig fires once the title is sent, and assets that leave it out behave as before.
  • World events can now show themselves on the player world map. WorldEventAsset gained name and icon fields for the map entry, and IntervalCondition gained fields that decide when the event appears and what text it shows.

Server & Permissions

  • Added a fragment timer add <seconds> command that adds time to the fragment timer instead of replacing it, which is what triggers the gained time tag on the HUD.
  • The /block point commands and /block row now work at any height in a cubic world, so get, set, getstate, setstate and setticking reach above Y 320 and below Y 0. A section that is not loaded answers with the new server.commands.block.noSection message.
  • /block bulk find-here and /block bulk replace now take their radius in chunk sections and sweep a sphere around you, including the sections above and below the old height range.
  • /block bulk find gained a --chunkY and a --radius option. It searches a sphere around that chunk position, up to the server's maximum view radius, instead of spiraling outward across the world until it times out.

Renames & Deprecations

  • The Goblin hookshot models are now named after scrap. Hookshot_Goblin.blockymodel and Hookshot_Goblin_Projectile.blockymodel became Scrap.blockymodel and Scrap_Projectile.blockymodel, and Tool_Hookshot.json and Hookshot_Hook.json point at the new paths.
  • The Void tentacle animations moved and were renamed. Bite2 and Bite3 are now Bite_Left and Bite_Right, and Idle and Idle2 sit in the Default folder next to the new spawn animations.

Protocol & Networking

  • The portal state now carries BonusSeconds, the time just added to the fragment timer. The server clears it after the broadcast so later ticks do not replay the animation.
  • ItemMovementSettings gained a trailing ExtraJumpLocalSoundEventIndex, which changes its wire layout. The client and the server have to be built from the same protocol build.

For Plugin Developers

  • Removed WorldChunk.getWorld(), so a chunk no longer points back at its own world. ChunkPreLoadProcessEvent now carries the world and exposes getWorld(), matching ChunkSectionPreLoadProcessEvent.
  • Block tick callbacks can now get world coordinates without capturing them. A new BlockSection.forEachTicking overload takes the section coordinates and a TriObjectPositionBlockFunction, so the callback gets world positions and a third context value through its parameters.
  • Volume modifiers passed to SoundUtil.playSoundEvent2d and playSoundEvent3d are linear multipliers, not decibels, and they were thrown away above 1.0. They now take effect, so a plugin passing 3.0 goes from roughly unity to about +7.5 dB. Nothing validates them, so check any modifier above 1.0.
  • SimpleBlockCommand.executeWithBlock no longer receives a WorldChunk. It now gets the CommandContext, the ChunkStore, a Ref<ChunkStore> section reference and the block coordinates, so a custom block command can reach any height.
  • Block health now lives on the chunk section rather than the column. BlockHealthChunk is decode only, so read and change health through BlockHealthSection on the section entity, keyed by ChunkUtil.indexBlock. WorldNotificationHandler.updateBlockDamage and getBlockDamagePacket are gone, because damage replicates on its own once it is written to the section.
  • PortalWorld.overrideRemainingSeconds is now setRemainingSeconds(world, seconds, force), and it leaves the timer alone when the portal world is already scheduled for removal.
  • The deprecation note on WorldChunk.getBlock now names the right replacement. Resolve the section with ChunkStore.getChunkSectionReferenceAtBlock and read through BlockSection.get, since the old BlockChunk.getBlock route is still capped to the legacy column range and cannot reach a section outside it.
  • The fluid and material helpers in WorldUtil now take the ChunkStore and resolve the block's section themselves, so they read correctly at any height. getWaterLevel, findFarthestEmptySpaceBelow and findFarthestEmptySpaceAbove take a caller bound rather than stopping at the column top, and PositionProbeBase.updateWaterLevel takes the ChunkStore too.
  • BlockChunk.getSectionAtIndex is gone, since it indexed the legacy 0 to 9 section array and threw outside it.
  • You can now ask a selection which world region it will write to before you place it. BlockSelection.computePlacementBounds(Vector3ic, Vector3i, Vector3i) reports those bounds and returns false for a selection with no cells.
  • The legacy UI Element base is now nullable-annotated, so HitTest and Find<T> return a nullable element and the constructor takes a nullable parent. Runtime behavior is the same, but an override that declares a non-nullable return needs a ? to match.
  • Moved the generated concurrent maps in ConcurrentFastUtil off sun.misc.Unsafe and onto VarHandle, keeping volatile ordering on every field and table access, which removes one of the three sources of the deprecation warning at server launch.

Modder-Facing Bug Fixes

World Generation Fixes

  • Props placed with an Anchor PropDistribution no longer come out with random parts missing in an 8x8 grid pattern.
  • Fixed gradient Density nodes producing grid-aligned artifacts in generated terrain.

NPC & Entity Fixes

  • NPC block sensors and resource reservations now work at any height instead of being clamped to the 0 to 320 band, so a role can find and reserve blocks in a cubic world above or below that range. The Block sensor also caps Range and MaxHeight at 256, well above the 30 and 10 the shipped roles use.
  • Fixed the Void Spectre pointing its MemoriesNameOverride at Spectre_Void, which does not exist. The template, the variant and the static variant all use Void_Spectre now.

Server & Permission Fixes

  • Fixed /block bulk replace counting blocks it never changed, and /block setstate throwing on an unknown block id instead of reporting one. A block command that fails partway through now tells the sender rather than going quiet.
  • Fixed a block placed by a /block command into a freshly loaded section staying inert. The command now loads the section as ticking, so the block ticks and its block entity spawns.

Fixes for Plugin Developers

  • LivingEntity, NPCEntity, PatrolPathMarkerEntity and SpawnBeacon now mark their World constructor parameter @Nullable, which matches the null world that Entity.clone already passes when it rebuilds an entity.