Denizen Script Language Explanations


Language Explanations explain components of Denizen in a more direct and technical way than The Beginner's Guide.


Showing 1 out of 78 language explanations...
NameSafety In Events
DescriptionOne of the more common issues in Denizen scripts (particularly ones relating to inventories) is
*event safety*. That is, using commands inside an event that don't get along with the event.

The most common example of this is editing a player's inventory, within an inventory-related event.
Generally speaking, this problem becomes relevant any time an edit is made to something involved with an event,
within the firing of that event.
Take the following examples:

on player clicks in inventory:
- take iteminhand
on entity damaged:
- remove <context.entity>


In both examples above, something related to the event (the player's inventory, and the entity being damaged)
is being modified within the event itself.
These break due a rather important reason: The event is firing before and/or during the change to the object.
Most events operate this way. A series of changes *to the object* are pending, and will run immediately after
your script does... the problems resultant can range from your changes being lost to situational issues
(eg an inventory suddenly being emptied entirely) to even server crashes!
The second example event also is a good example of another way this can go wrong:
Many scripts and plugins will listen to the entity damage event, in ways that are simply unable to handle
the damaged entity just being gone now (when the event fires, it's *guaranteed* the entity is still present
but that remove command breaks the guarantee!).

The solution to this problem is simple: Use "after" instead of "on".

after player clicks in inventory:
- take iteminhand
after entity damaged:
- if <context.entity.is_spawned||false>:
  - remove <context.entity>

This will delay the script until *after* the event is complete, and thus outside of the problem area.
And thus should be fine. One limitation you should note is demonstrated in the second example event:
The normal guarantees of the event are no longer present (eg that the entity is still valid) and as such
you should validate these expectations remain true after the event (as seen with the 'if is_spawned' check).
(See also Language:Script Event After vs On)

If you need determine changes to the event, you can instead use 'on' but add a 'wait 1t' after the determine but before other script logic.
This allows the risky parts to be after the event and outside the problem area, but still determine changes to the event.
Be sure to use 'passively' to allow the script to run in full.

on player clicks in inventory:
- determine passively cancelled
- wait 1t
- take iteminhand
on entity damaged:
- determine passively cancelled
- wait 1t
- if <context.entity.is_spawned||false>:
  - remove <context.entity>
GroupScript Events
Sourcehttps://github.com/DenizenScript/Denizen/blob/dev/plugin/src/main/java/com/denizenscript/denizen/events/BukkitScriptEvent.java#L915