- **Breaking Change: Structures save and load themselves: `structure:save` and `Structure:load`**
- They replace `Server:saveStructure` and `Server:loadStructure`. The returned path has "/" between the folders on every system.
```lua
struct:save("mickkay:tower") -- before: spell.server:saveStructure("mickkay:tower", struct)
local loaded = Structure:load("mickkay:tower") -- before: spell.server:loadStructure("mickkay:tower")
```
- **Breaking Change: A skin is a `Skin` object**
- `player.skin` is the `Skin` a player wears (`nil` for a default skin), no longer an account name. Assign a `Skin` to put it on, `nil` for a default skin. `Player:setSkin` and `Player:getSkin` are gone.
- `Skin:lookup(account)` gets an account's skin from Mojang; `skin:save(path)` and `Skin:load(path)` keep it in the world folder.
```lua
local skin = Skin:lookup("jeb_") -- before: player:setSkin("jeb_")
if skin then player.skin = skin end
```
- **Breaking Change: `MobEntity.lookAt` is now `MobEntity.watchTarget`**
- `lookAt` is now a function that turns any entity once, see below.
- **Breaking Change: A mob's attack task counts `task.hits` and `task.shots` apart**
- `task.hits` counts the hits that hurt the target, `task.shots` the shots fired. `task.hits` counted both.
- **Breaking Change: `ChatMessageEvent` also fires for `/say` and `/me` of anyone**
- `evt.sender` is the `Entity` or `Spell` that sent the message (`nil` for a command block or the console), not always a player. New: `evt.senderName` and `evt.kind` ("chat", "say" or "emote").
- **New: Bot players: players without a client that spells control**
- `Bot:spawn(name, pos)` makes a bot that joins like a player, so every event fires as for a player. Use bots to play-test a mini-game, or as companions.
- A bot acts like a player at the keyboard. Tasks let it walk along paths it finds, follow, flee, fight, stay, break and place blocks, and fill or empty containers. `BotMessageEvent` and `BotSoundEvent` tell what it sees and hears. See [Bot](https://wizards-of-lua.net/api/Bot/).
- **New: The Squire example**
- A bot that follows you, fights at your side and holds a spot: `/squire hire <name>`.
- **New: `Entity:lookAt(target)` turns any entity once to a position or another entity**
- `spell:lookAt` takes an entity too.
- **New: `Player.flying` tells and sets whether a player flies**
- **New: An interceptor doesn't get the events it causes itself**
- So a callback that answers each chat message in the chat doesn't call itself without end.
- **Fix: The Journey example works on Minecraft 1.21.5, and `/journey cancel` says when there is no journey to cancel**
- **Fix: An invalid value for `sneaking` names `sneaking` in the error message**
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }