Actions - MarkusBordihn/BOs-Easy-NPC GitHub Wiki

Actions 🎮

Actions make NPCs interactive. They can run commands, open dialogs, open trading, interact with blocks, or update scoreboards.

Typical examples:

  • /say Hello, @initiator
  • /give @initiator stone
  • /scoreboard players add @initiator coins 1
  • /easy_npc dialog open @npc @initiator default

Default permissions limit what an NPC may do. If you use command actions on servers, also read Permissions.

Action Lists 📋

Each action list can contain multiple entries. Actions run from top to bottom in the listed order.

Action List screen

Action Types ⚙️

The current action types are:

  • Command
  • Close Dialog
  • Interact Block
  • Open Trading
  • Open Default Dialog
  • Open Dialog
  • Open Dialog (Conditional)
  • Scoreboard
  • Message

Command

Command actions are the most flexible option. Use them for rewards, messages, scripted events, or integration with other mods.

Action Options screen

  • Leave Execute as player disabled if the command should run as the NPC
  • Enable it only when the command must run in the interacting player's context
  • Commands executed as player must be explicitly allowlisted by the server in config/easy_npc/security.cfg (executeAsUserCommandAllowList.<LEVEL>); list command names only, wildcards are not supported, and a restart is required after editing
  • The effective command authority is still capped by the NPC's stored command level
  • If a command only needs the player as a target, prefer running it as the NPC with @initiator (for example /tp @initiator …) instead of enabling Execute as player

See Permissions for the full allowlist rules and troubleshooting.

Close Dialog

Closes the currently open dialog screen.

Close Dialog screen

Interact Block

Makes the NPC trigger a block interaction at a target position.

Interact Block screen

Open Trading

Opens the NPC trading screen.

Open Trading Screen screen

Open Default Dialog

Opens the default dialog for the NPC.

Open Default Dialog screen

Open Dialog

Opens a named dialog entry by label, regardless of the conditions defined on the target dialog.

Open Named Dialog screen

Open Dialog (Conditional)

Opens a named dialog entry by label only if all conditions of the target dialog are met for the player; otherwise nothing happens. Use this for dialogs gated by an execution limit (e.g. "max 3 per day"), required items, scores, or other conditions. The unconditional Open Dialog action ignores those conditions, so both options remain available.

Scoreboard

Scoreboard actions change a value for the interacting player. This is useful for quests, shop progress, currencies, unlock flags, or counters.

Supported operations:

  • increase
  • decrease
  • set

Format:

operation:scoreboard_name:value

Examples:

  • increase:coins:5
  • decrease:reputation:1
  • set:quest_stage:3

Message

Lets the NPC say something without a command and without the permissions a command needs. Pick one or more outputs:

  • Chat for nearby players — every player within 16 blocks who can see the NPC gets <Name> Text in the chat
  • System message for the player — only the player who triggered the action, without a name in front of it. On Spawn, On Kill and On State Change have no player, so this option cannot be chosen there
  • Speech bubble above the NPC — shown for at least 5 seconds to the same players as the chat output. Longer texts remain visible longer, up to 18 seconds

Up to six message texts can be added. One is selected at random whenever the action runs, and the same selected text is used for all enabled outputs. The message texts support the same macros and formatting as a dialog text, for example @initiator, <red>…</red> and <br>. A text matching the translation key format (text.my_pack.npc.hello) is translated on the client; all other text is used as written. Macros and formatting are not applied to translation keys.

Send to decides who receives the message:

  • NEARBY - the chat output and the speech bubble go to every player within 16 blocks, the system message goes to the player who triggered the action. This is the default and the previous behavior.
  • INITIATOR - only the player who triggered the action, so bystanders neither read nor see it.
  • OWNER - only the owner of the NPC. Nothing is sent while the owner is offline or out of range.

Combine OWNER with a time based event to build a companion that talks to its owner alone. Note that On Spawn, On Kill and On State Change have no triggering player, so INITIATOR sends nothing there.

Sender Name replaces the name in front of the chat output, for example for a narrator or an unknown voice. Leave it empty to use the name of the NPC. A name that belongs to an existing player is ignored and the NPC name is used instead, so an NPC cannot imitate a player.

The speech bubble is drawn from assets/easy_npc/textures/gui/speech_bubble.png. A resource pack can replace that file to use its own style: the left part (0,0 to 32,32) is the body, stretched with an 8 pixel border, and the part next to it (32,0 to 48,8) is the tail below the body. The shipped texture has a light body, so keep the inside light — the text is drawn in a dark color.

Action Events 🧭

Actions can be attached to different events.

Basic Events

  • On Interaction
  • On Hurt
  • On Death
  • On Kill
  • On Trade

On Trade runs after a successful purchase. Use it when every completed trade should trigger the same logic.

Basic Action Setup screen

Dialog Events

  • On Open Dialog
  • On Close Dialog
  • On Button Click

Dialog Action Setup screen

Distance Events

  • Near
  • Close
  • Very Close
  • In Touch

These actions trigger once when a player enters the matching range, and can trigger again after the player leaves and returns.

Distance Action Setup screen

Trade Actions vs On Trade 🛒

Trade-related logic can be attached in two different places:

  • On Trade for logic that should run after every successful trade
  • per-offer trade actions in Trading for logic that should run only for one specific offer

Use On Trade for generic shop behavior, for example:

  • add one global purchase counter
  • play the same reward command for all offers

Use per-offer trade actions when individual offers should behave differently, for example:

  • rare item gives a bonus
  • quest item advances a quest stage
  • one special offer opens a follow-up dialog

Conditions 🎯

Actions can also have conditions. An action only runs if all of its conditions match (AND logic). For OR behavior, split the logic across several actions, each with its own condition.

Open the condition editor from the action editor via the Conditions button.

Available condition types:

Condition Checks
Scoreboard A scoreboard objective compared against a value (e.g. coins >= 10)
Execution limit How often the action may run per player (per minute/hour/day/week/month/lifetime)
Has item in inventory The player carries an item, optionally a minimum quantity
Has item in hand The player holds an item in the main hand, off hand, or either
Advancement The player has completed an advancement
Experience level The player's XP level compared against a value
Player health The player's health in percent compared against a value
NPC health The NPC's own health in percent compared against a value
Entity health The health in percent of another entity, addressed by its UUID
Player tag The player has a scoreboard tag
Relationship The player is the owner, or is in a matching, friendly or hostile faction
Team The player is a member of a team
Game mode The player is in a specific game mode
Time of day The world time (0-23999) compared against a value
Weather The current weather is clear, rain, or thunder
Fallback Runs only if no other action in the set executed

Comparisons

Value-based conditions use an operator: ==, !=, >, >=, <, <=. That also covers the negated case, so you can require that a player does not meet a condition.

Item quantities

Has item in inventory and Has item in hand default to a quantity of 1. Set a higher number to require more, e.g. 10 diamonds. A quantity of 0 or 1 both mean "at least one". For the inventory check the count is summed across all matching stacks.

Has item in hand can additionally be limited to the main hand, the off hand, or accept either one.

Execution limits

Execution limit counts per player and per action. The duration decides when the counter resets: per minute, hour, day, week, month, or lifetime (never resets).

This is what makes "one reward per day" or "this quest can be started only once" work without any scoreboard setup.

Health conditions

All three health conditions compare a percentage, not absolute hearts, so they keep working when the max health changes:

  • Player health - the interacting player, e.g. "only heal below 50%"
  • NPC health - the NPC itself, e.g. a different dialog when the guard is wounded
  • Entity health - another entity by UUID, e.g. "the boss is below 25%, open the retreat dialog". Copy the UUID from the target NPC's configuration screen.

Relationship

Relationship compares the player against this NPC:

  • OWNER / NOT_OWNER - the player is (or is not) the owner. NOT_OWNER also matches when the NPC has no owner at all.
  • SAME_FACTION / NOT_SAME_FACTION - the player belongs to the same faction, which for a player is their scoreboard team (see Factions).
  • FRIENDLY_FACTION / HOSTILE_FACTION - the faction of the NPC is (or is not) hostile towards the group of the player.

The optional faction field compares against that faction instead of the faction of the NPC. Leave it empty for the usual case.

For a companion, Relationship = OWNER limits a time based message to its owner and skips it while the owner is away.

Faction conditions are evaluated on the server. In the dialog screen, a button gated by FRIENDLY_FACTION or HOSTILE_FACTION remains available until server validation.

Time and weather

  • Time of day compares the raw world time inside a day. Useful values: 0 sunrise, 6000 noon, 12000 sunset, 18000 midnight. A shop that closes at night is Time of day < 12000.
  • Weather matches CLEAR, RAIN, or THUNDER.

Both are evaluated in the dimension the player is in.

Use cases:

  • only run an action if coins >= 10
  • only trade if the player holds at least 10 diamonds
  • let a reward happen only once per day (execution limit)
  • unlock a dialog button after a scoreboard milestone
  • a merchant that only trades during the day
  • a shelter NPC that only invites players in during a thunderstorm

Placeholders 🧩

These placeholders are available in actions:

Placeholder Description
@npc NPC name
@npc-uuid NPC UUID
@initiator Player name
@initiator-uuid Player UUID

Practical Examples 💡

Some useful patterns:

  • NPC shopkeeper: On Trade adds a global customer score
  • quest merchant: per-offer action updates quest_stage
  • teleport guide: dialog button runs a command action
  • warning NPC: distance action fires once when the player gets close

Default Interaction Actions ⭐

New NPCs can start with default interaction behavior. If dialog or trading is configured, the NPC may already contain:

  • Open Default Dialog
  • Open Trading

You can keep, reorder, or remove these actions in the normal action editor.

Default Interaction Actions screen

⚠️ **GitHub.com Fallback** ⚠️