Skript 2.12.0-pre1
Today, we are excited to celebrate the beginning of the second half of the year with a new Skript pre-release! Skript 2.12.0-pre1 is now available! This release includes dozens of new features and bug fixes, along with early support for 1.21.6/7.
Below, you can familiarize yourself with the changes. Additionally, by clicking here, you can view the list of new syntax on our documentation site. As always, report any issues to our issues page!
Per our release model, we plan to release 2.12.0 on July 15th. We may release additional pre-releases before then should the need arise.
We would also like to welcome a new addition to the team, @Absolutionism!
Happy Skripting!
Major Changes
Ephemeral Variables
Ephemeral variables (or ram vars, or memory vars) are now fully implemented by default for all users. These are global variables that are not saved between restarts. To make a variable ephemeral, add a hyphen (-
) to the start of its name: {-var}
. These variables are about 2.5x faster to change compared to normal global variables. You do not need to do anything to enable them.
Function Overloading
Note
The script reflection
experiment, which includes syntax for dynamically referencing and executing functions, does not yet support working with overloaded functions.
Function overloading enables creating functions that have the same name but different parameters types/parameter counts.
function send_welcome(p: player):
send_welcome({_p}, false)
function send_welcome(p: player, first_time: boolean):
if {_first_time} is true:
send "Welcome to our server for the first time, %name of {_p}%!" to {_p}
else:
send "Welcome back to our server, %name of {_p}%!" to {_p}
Local Variable Type Hints (Experimental)
Note
This feature is currently experimental and can be used by enabling the type hints
experiment.
Local variable type hints enable Skript to understand what kind of values your local variables will hold at parse time. Consider the following example:
set {_a} to 5
set {_b} to "some string"
... do stuff ...
set {_c} to {_a} in lowercase # oops i used the wrong variable
Previously, the code above would parse without issue. However, Skript now understands that when it is used, {_a}
could only be a number (and not a text). Thus, the code above would now error with a message about mismatched types.
Please note that this feature is currently only supported by simple local variables. A simple local variable is one whose name does not contain any expressions:
{_var} # can use type hints
{_var::%player's name%} # can't use type hints
Runtime Error Catching (Experimental)
Note
This feature is currently experimental and can be used by enabling the error catching
experiment.
A new catch [run[ ]time] error[s]
section allows you to catch and suppress runtime errors within it and access them later with [the] last caught [run[ ]time] errors
.
catch runtime errors:
...
set worldborder center of {_border} to {_my unsafe location}
...
if last caught runtime errors contains "Your location can't have a NaN value as one of its components":
set worldborder center of {_border} to location(0, 0, 0)
Damage Sources (Experimental)
Note
This feature is currently experimental and can be used by enabling the damage sources
experiment.
Caution
Note that type
has been removed as an option for the 'damage cause' expression as damage cause
and damage type
now refer to different things.
Damage sources are a more advanced and detailed version of damage causes. Damage sources include information such as the type of damage, the location where the damage originated from, the entity that directly caused the damage, and more.
Below is an example of what damaging using custom damage sources looks like:
damage all players by 5 using a custom damage source:
set the damage type to magic
set the causing entity to {_player}
set the direct entity to {_arrow}
set the damage location to location(0, 0, 10)
For more details about the syntax, visit damage source on our documentation website.
Contributing Updates
We are now allowing contributors to release their code contributions under the more-permissive MIT License. For more information, please review our LICENSING.md file.
⚠ Breaking Changes
- When using
index of "a" in "b"
, values that do not appear in the second string will now returnnone
instead of the previous-1
. - The
is enchanted with
condition now looks for exact levels instead of the specified level or better. Old behavior can be replicated withif {_item} is enchanted with sharpness 2 or better
. Some examples:
if {_item} is enchanted with sharpness 2 # only passes for sharpness 2. Previous behavior allowed sharpness of 2 or greater to pass.
if {_item} is enchanted with sharpness 2 or better # sharpness 2+
if {_item} is enchanted with sharpness 2 or worse # sharpness 2 or 1
if {_item} is enchanted with sharpness # sharpness of any level
- An infinite timespan literal was added, meaning Timespan math operations can now result in an infinite timespan value (just like numbers).
- The parsing behavior of the 'amount' expression has changed. Given an expression like
amount of {a::*}, "b"
, it was before parsed as(amount of {a::*}), "b"
, but it is now parsed asamount of ({a::*}, "b")
. Use parentheses as necessary to clarify your intent. - For the old 'beacon values' expression,
beacon
is now a required keyword for therange
andtier
expressions. - The
remove all
changer for the 'custom model data' expression has been removed. It functioned the same asremove
. head
has been removed as an option for the 'player skull' expression ashead of player
conflicts with the 'head location' expression.type
has been removed as an option for the 'damage cause' expression asdamage cause
anddamage type
now refer to different things.- The 'load world' effect now requires
world
. - The API method
RegistryParser#getAllNames
has been removed in favor ofRegistryParser#getCombinedPatterns
(from thePatternedParser
interface). - API methods for the
since
documentation field have changed on SkriptEventInfo:SkriptEventInfo#getSince() (String) -> SkriptEventInfo#getSince() (String[])
BukkitSyntaxInfos.Event.since() (String) -> BukkitSyntaxInfos.Event.since() (Collection<String>)
BukkitSyntaxInfos.Event.Builder.since(String) -> BukkitSyntaxInfos.Event.Builder.addSince(String)
- (API) Syntax ordering is no longer based on registration order when a priority is shared. This may expose syntax conflicts if this behavior was depended on.
Changelog
Additions
- #4154 Adds support for boolean values to the 'toggle' effect and an 'inverse boolean' expression to obtain the inverse of a boolean (at long last).
- #6902 Adds a 'buried item' expression and a 'dusted stage' expression for working with brushable blocks.
- #7495 Adds ephemeral variables (starting with
-
) which are cleared when the server restarts. - #7561 Adds an 'except' expression which provides a simple way to filter values from a list.
- #7658 Adds an 'On-screen kick message' expression to get and change the on-screen message that appears when a user is kicked, usable in the kick event.
- #7685 Adds support for the Catalan language (thanks to @TwistedWar3713, @Lukarius11, and @ItzDuck364 for their language insights).
- #7707 Adds support for the 'item cooldown' syntax to respect cooldown groups (cooldown components) defined on items.
- #7738 Adds an 'exact item' expression that acts like creative-mode middle-click, copying the block's data exactly.
- #7745 Adds a 'vault display item' event for when a trial vault displays an item.
- #7746 Adds a 'villager career change' event for when villagers change professions along with the ability to obtain the reason why.
- #7748 Adds a condition and effect for working with shivering striders.
- #7751 Adds support for function overloading, enabling functions to have the same name but different parameters.
- #7803 Adds the word
along
as an option in the 'push' effect:push player along vector(1,1,1) at speed 3
. - #7807 Adds support for using the expanded custom model data system to the 'custom model data' expression. Note that
remove all
changer support has been removed. - #7808 Adds a warning for ambiguous command arguments where expressions like
arg-1
could be misinterpreted as(arg) - 1
. - #7823 Adds experimental syntax for catching and suppressing runtime errors. See the available experiments section below for more information.
- #7830 Adds support for printing errors to the 'enable/disable/unload/reload script' effect.
- #7841 Adds support for syntax simplification, which enables parse time pre-computation of some syntax that will always have the same result.
- #7846 Adds support for the new 1.21.5 pig variants.
- #7851 Adds a warning for when literals that can be interpeted as multiple types are used and Skript cannot determine the intended type.
- #7858 Adds error messages for experimental syntax that is used when the experiment is disabled.
- #7866 Adds support for cow variants.
- #7868 Adds support for chicken variants.
- #7892 Adds experimental support for local variable type hints. This allows Skript to determine what kind of values your local variables may hold at parse time. See the available experiments section below for more information.
- #7897 Expands the 'arrow attached block' expression to support multiple blocks, as arrows may be attached to multiple blocks. The existing single expression has been deprecated on versions where the plural expression is available, as it is unreliable.
- #7903 Adds a 'harvest block' event for when a block is harvested (berry bushes, glowberries, etc.).
- #7905 Adds a new
event-entity type
event value for entity related events. - #7906 Adds saddle and dynamic equipment slot support to the 'armor slot' expression.
- #7909 Adds a 'keyed' expression which allows explicitly passing/including the keys of an expression alongside its values. For example, you can preserve/include keys (indices) when setting a list variable to another list variable or when providing a list variable as the argument of a function.
- #7914 Adds a 'first empty slot in inventory' expression to obtain the first empty slot in inventories.
- #7933 Adds scientific notation (e.g.
1.23E4
,10e-10
) to numbers. - #7942 Function names can now start with an underscore.
- #7949 Adds support for resetting sent block changes from the 'send block change' effect.
- #7950 Adds support to the 'push' effect for pushing/pulling entitites towards/away from a location.
- #7951 Adds support for deleting the 'spawner type' of a spawner.
- #7956 Adds support for an 'infinite' timespan. Note that now, just like numbers, math operations for Timespans can now result in an infinite timespan value.
- #7957/#7982/#7983 Implement early support for 1.21.6/7.
- #7961 Adds support for literals in the 'amount' expression. Note that, as a result, the parsing behavior has now changed. Given an expression like
amount of {a::*}, "b"
, it was before parsed as(amount of {a::*}), "b"
, but it is now parsed asamount of ({a::*}, "b")
. Use parentheses as necessary to clarify your intent.
Changes
- #7325 Improves the 'indices of' expression to allow accessing the index/position of a specific value in a list. Note that values that are not found in a list or a string now return
none
instead of-1
. - #7729 Splits the 'beacon values' expression into multiple new expressions: 'beacon effects', 'beacon range', and 'beacon tier'. Note that the
range
andtier
expressions now requirebeacon
in their syntax. - #7742 Cleans up the 'hash' expression and adds SHA-384 and SHA-512. A warning is now printed when using the MD5 algorithm.
- #7816 The 'is enchanted' condition now looks for exact enchantments, with
or better
andor worse
added as newly available comparison options. - #7840 Improves the existing comparisons for offline players and offline players-strings.
- #7913 The
aliases
folder will now be created automatically so that users know where to place custom aliases. - #7944 Tweaks the 'target entity' expression to make the ray size option more grammatically correct.
- #7965 Splits the 'special number' expression into multiple literal expressions: 'infinity', 'NaN', and 'negative infinity'
Bug Fixes
- #7654 Fixes Skript's documentation using incorrect pages and formatting.
- #7674 Fixes an issue where the
event-item
in a 'craft' event often returnedair
due to the recipe being complex. - #7879 Fixes an issue where syntax removals using the new Registration API often failed.
- #7917 Fixes an issue where the
raid omen
effect was incorrectly given the aliasbad omen
. - #7928 Fixes an issue where sorting lists with duplicate values returned a list with only a single instance of that value.
- #7935 Fixes incorrect documentation for the 'expand/shrink world border' effect.
- #7938 Fixes an issue where using the 'name' expression with default variables could cause an exception.
- #7945 Fixes a bug where the 'is within' condition incorrectly handled
or
lists. - #7947 Fixes comparisons between enchantments and enchantment types:
if sharpness 1, efficiency 3, and knockback 2 contains sharpness
. - #7951 Fixes multiple issues with using and comparing against llamas/trader llamas.
- #7964 Fixes an issue with setting variables during script loading when asynchronous loading is enabled.
- #7971 Fixes some issues with comparing pig variants and that variants could not be used with baby pigs.
- #7976 Fixes an issue where arithmetic syntax could fail to resolve valid operations.
- #7986 Fixes an issue on newer versions where adding items to an inventory could result in other slots being mistakenly deleted.
- #7989 Fixes an issue where
next
/previous
'loop-value' could fail to reset in-between loops.
API Changes
- #7256 Adds API to allow the setting of custom default values for types.
- #7551 Integrates the Registration API into SkriptParser and syntax class parse methods. Addons using SkriptParser methods directly may need to be recompiled, though there should be no breaking changes.
- #7709 Updates SkriptEventInfo (and its Registration API equivalent) to support passing an array for the
since
documentation field. Some methods have had their signatures changed and addons using them will need to be updated. - #7710 Cleanup to the ExprTool class and EquipmentSlot conversion methods for BukkitUtils.
- #7778 Adds a preInit() method intended to help with doing common init work for families of syntaxes, rather than having to hijack init() and create a different signature for the children to implement.
- #7791 Adds a spawnTestEntity helper method for JUnit tests.
- #7832 Removes many unnecessary version checks for versions Skript no longer supports.
- #7841 The syntax simplification API is now used by the parser. For more information, review the pull request's description.
- #7851 Adds a PatternedParser utility interface and replaces the
RegistryParser#getAllNames
method withRegistryParser#getCombinedPatterns
(from thePatternedParser
interface). - #7858 Adds ExperimentData utility class and SimpleExperimentalSyntax utility interface to simplify the work needed by syntax to restrict based on the set experiments.
- #7879 Registered syntax are no longer ordered by when they were registered. Priorities should be used if precise registration order is required.
- #7891 Improves the return types for many expressions via
Expression#possibleReturnTypes()
andExpression#canReturn()
. - #7892 Adds experimental support for local variable type hints. If you have syntax that modifies variables (and may result in their type being changed), you you may need to support this feature. For more information, review the pull request's description (see "API Support").
- #7904 Fixes a conflict between the 'player skull' expression and the 'head location' expression. Note that
head
has been removed as an option for theplayer skull
expression. - #7909 Significantly expands (and reworked to some extent) the Keyed Expression API. For more information about the changes, review the pull request's description.
- #7918 Adds a Javadoc description for the
Type
generic parameter in theAnyContains
interface. - #7927 Adds a getter method for the expression used in
PropertyCondition
. - #7929 Implements preInit() for Effect, Condition, and Section, allowing runtime errors to be used more easily. Adds a
#isSectionOnly()
method in SectionExpression allowing the ability to check if it requires a Section. - #7971 Improves documentation for EntityData.
- #7972 Switches entitydata age/plurality from parse marks to parse tags.
Click here to view the full list of commits made since 2.11.2
Notices
Experimental Features
Experimental features can be used to enable syntax and other behavior on a per-script basis. Some of these features are new proposals that we are testing while others may have unsafe or complex elements that regular users may not need.
While we have tested the available experiments to the best of our ability, they are they are still in development. As a result, they are subject to change and may contain bugs. Experiments should be used at your own discretion.
Additionally, example scripts demonstrating usage of the available experiments can be found here.
Enable by adding A new kind of loop syntax that stores the loop index and value in variables for convenience.
This can be used to avoid confusion when nesting multiple loops inside each other.
All existing loop features are also available in this section.
Enable by adding A collection that removes elements whenever they are requested.
This is useful for processing tasks or keeping track of things that need to happen only once.
Queues can be looped over like a regular list.
Enable by adding This feature includes:
Enable by adding Local variable type hints enable Skript to understand what kind of values your local variables will hold at parse time. Consider the following example:
Previously, the code above would parse without issue. However, Skript now understands that when it is used, Please note that this feature is currently only supported by simple local variables. A simple local variable is one whose name does not contain any expressions:
Enable by adding A new Enable by adding Note that Damage sources are a more advanced and detailed version of damage causes. Damage sources include information such as the type of damage, the location where the damage originated from, the entity that directly caused the damage, and more.
Below is an example of what damaging using custom damage sources looks like:
For more details about the syntax, visit damage source on our documentation website.
Click to reveal the experiments available in this release
For-Each Loop
using for loops
to your script.
for {_index}, {_value} in {my list::*}:
broadcast "%{_index}%: %{_value}%"
for each {_player} in all players:
send "Hello %{_player}%!" to {_player}
Queue
using queues
to your script.
set {queue} to a new queue of "hello" and "world"
broadcast the first element of {queue}
# "hello" is now removed
broadcast the first element of {queue}
# "world" is now removed
# queue is empty
set {queue} to a new queue of all players
set {player 1} to a random element out of {queue}
set {player 2} to a random element out of {queue}
# players 1 and 2 are guaranteed to be distinct
Script Reflection
using script reflection
to your script.
Local Variable Type Hints
using type hints
to your script.
set {_a} to 5
set {_b} to "some string"
... do stuff ...
set {_c} to {_a} in lowercase # oops i used the wrong variable
{_a}
could only be a number (and not a text). Thus, the code above would now error with a message about mismatched types.
{_var} # can use type hints
{_var::%player's name%} # can't use type hints
Runtime Error Catching
using error catching
to your script.
catch [run[ ]time] error[s]
section allows you to catch and suppress runtime errors within it and access them later with [the] last caught [run[ ]time] errors
.
catch runtime errors:
...
set worldborder center of {_border} to {_my unsafe location}
...
if last caught runtime errors contains "Your location can't have a NaN value as one of its components":
set worldborder center of {_border} to location(0, 0, 0)
Damage Sources
using damage sources
to your script.
type
has been removed as an option for the 'damage cause' expression as damage cause
and damage type
now refer to different things.
damage all players by 5 using a custom damage source:
set the damage type to magic
set the causing entity to {_player}
set the direct entity to {_arrow}
set the damage location to location(0, 0, 10)
Help Us Test
We have an official Discord community for beta testing Skript's new features and releases.
Thank You
Special thanks to the contributors whose work was included in this version:
- @Absolutionism
- @APickledWalrus
- @Asleeepp
- @Burbulinis
- @ChickChicky ⭐ First contribution! ⭐
- @Efnilite
- @erenkarakal
- @Fusezion
- @LalitNarayanYadav ⭐ First contribution! ⭐
- @Moderocky
- @Mr-Errors ⭐ First contribution! ⭐
- @nopeless
- @OfficialDonut
- @Olyno
- @sovdeeth
- @TheLimeGlass
- @TheMug06
- @TwistedWar3713 ⭐ First contribution! ⭐
- @UnderscoreTud
As always, if you encounter any issues or have some minor suggestions, please report them at https://github.com/SkriptLang/Skript/issues.
If you have any bigger ideas or input for the future of Skript, you can share those too at https://github.com/SkriptLang/Skript/discussions.