Skip to content
BasaltSoftware
Bedrock 1.26.60

Site colour

Discord
Esc

    ↑↓ moveEnter openEsc close

    Keyboard shortcuts
    Ctrl K
    Search the whole site, from any page
    /
    Jump to the sidebar search, or search the whole site where there isn't one
    Enter
    Open the top search result
    Esc
    Clear the search, or close this panel
    ?
    Show these shortcuts
    Plugin API

    Script events

    Trigger plugin code with the /scriptevent command, and send messages between plugins.

    A script event is a named message delivered to every plugin. Anyone who can run the /scriptevent command can send one, and so can a plugin. They are the simplest way to:

    • give operators a way to trigger plugin code without registering a full command,
    • let the terminal poke a plugin, for example from a maintenance script,
    • pass messages from one plugin to another.

    Subscribe to system.afterEvents.scriptEventReceive:

    import { system, world } from "@minecraft/server";
    system.afterEvents.scriptEventReceive.subscribe((event) => {
    if (event.id !== "event:start") return;
    world.sendMessage(`§6The event is starting! ${event.message}`);
    });

    Then, as an operator or from the terminal:

    /scriptevent event:start Meet at spawn

    The event has four fields:

    Field Meaning
    id The message id: the first word after /scriptevent.
    message Everything after the id, as one string. Empty if nothing was given.
    sourceType ScriptEventSource.Entity when a player ran the command, ScriptEventSource.Server when the terminal or a plugin sent it.
    sourceEntity The player who ran the command. undefined otherwise.

    Every plugin receives every script event, so always check id first and ignore what is not yours. Use a namespace of your own before the colon to avoid clashing with other plugins.

    /scriptevent <messageId> [message]

    /scriptevent is an operator command and also works in the terminal, without the slash. The message is free text; it is up to the plugin to make sense of it.

    A small dispatcher keeps things tidy when one plugin handles several events:

    import { system, world, ScriptEventSource, Player } from "@minecraft/server";
    const handlers: Record<string, (message: string, player?: Player) => void> = {
    "arena:open": () => world.sendMessage("§aThe arena is open."),
    "arena:close": () => world.sendMessage("§cThe arena is closed."),
    "arena:say": (message) => world.sendMessage(`§7[Arena] ${message}`),
    "arena:whoami": (_message, player) => player?.sendMessage(`You are ${player.name}`),
    };
    system.afterEvents.scriptEventReceive.subscribe((event) => {
    const handler = handlers[event.id];
    if (!handler) return;
    const player =
    event.sourceType === ScriptEventSource.Entity && event.sourceEntity instanceof Player
    ? event.sourceEntity
    : undefined;
    handler(event.message, player);
    });

    The message is a string. To pass more than one value, send JSON and parse it, guarding against input that is not valid:

    import { system, world } from "@minecraft/server";
    system.afterEvents.scriptEventReceive.subscribe((event) => {
    if (event.id !== "shop:setprice") return;
    try {
    const { item, price } = JSON.parse(event.message);
    world.setDynamicProperty(`shop:price:${item}`, Number(price));
    } catch {
    console.warn(`shop:setprice needs JSON, got: ${event.message}`);
    }
    });
    /scriptevent shop:setprice {"item":"diamond","price":25}

    system.sendScriptEvent sends a script event from code. Every plugin’s scriptEventReceive handlers hear it, including the sender’s own, with sourceType set to ScriptEventSource.Server.

    import { system, world } from "@minecraft/server";
    world.afterEvents.playerSpawn.subscribe(({ player, initialSpawn }) => {
    if (!initialSpawn) return;
    system.sendScriptEvent("economy:joined", JSON.stringify({ name: player.name }));
    });

    Another plugin can then react without either plugin importing the other:

    import { system } from "@minecraft/server";
    system.afterEvents.scriptEventReceive.subscribe((event) => {
    if (event.id !== "economy:joined") return;
    const { name } = JSON.parse(event.message);
    console.log(`Rewards plugin noticed ${name} joining`);
    });

    The id passed to sendScriptEvent must have a namespace (namespace:name); without one the call throws.

    This is the recommended way for plugins to talk to each other. Plugins cannot import one another’s files, and dynamic properties are private to each plugin.

    Use a script event when Use a custom command when
    The trigger is for operators, automation or other plugins Ordinary players will run it
    A free-text message is enough You want typed parameters and auto-complete
    You want something quick to wire up You want it listed in /help with a description

    Script events are operator-only when sent by command, so they are not a way to give regular players a command.

    scriptEventReceive is an after event: it is delivered once the command has finished, and there is nothing to cancel. Because of that, handlers can read and change the world freely, with none of the restrictions of before events.