Helpers & Registries
Helpers & Registries
Section titled “Helpers & Registries”Ceremony scripts have access to a set of built-in helpers and pre-wrapped Minecraft registries. These globals are available in every script without imports.
Vec3 provides 3D vector math for positions, directions, distances, and movement calculations. It supports both static operations (take values, return new values) and instance methods (operate on a Vec3Instance).
Creating Vectors
Section titled “Creating Vectors”// From three numbersconst a = Vec3.of(10, 65, -30);
// From an object with x, y, z propertiesconst b = Vec3.of({ x: 10, y: 65, z: -30 });
// Zero vector constantconst origin = Vec3.ZERO; // (0, 0, 0)Vec3Like Type
Section titled “Vec3Like Type”Many Vec3 methods accept a Vec3Like parameter, which can be any of:
| Format | Example |
|---|---|
| Vec3Instance | Vec3.of(1, 2, 3) |
| Object with x, y, z | { x: 1, y: 2, z: 3 } |
| Array of three numbers | [1, 2, 3] |
This means you can pass player positions, block positions, or raw arrays interchangeably:
const playerPos = wrapPlayer(player).pos;const distance = Vec3.distance(playerPos, [100, 65, 200]);Static Methods
Section titled “Static Methods”Static methods take Vec3Like parameters and return new Vec3Instance values.
| Method | Signature | Description |
|---|---|---|
Vec3.of | (x, y, z) or ({x, y, z}) | Create a new Vec3Instance |
Vec3.add | (a: Vec3Like, b: Vec3Like) | Add two vectors |
Vec3.subtract | (a: Vec3Like, b: Vec3Like) | Subtract b from a |
Vec3.scale | (v: Vec3Like, scalar: number) | Multiply vector by scalar |
Vec3.normalize | (v: Vec3Like) | Return unit vector (length 1) |
Vec3.distance | (a: Vec3Like, b: Vec3Like) | Euclidean distance between two points |
Vec3.distanceSq | (a: Vec3Like, b: Vec3Like) | Squared distance (faster, no sqrt) |
Vec3.direction | (from: Vec3Like, to: Vec3Like) | Normalized direction from one point to another |
Vec3.dot | (a: Vec3Like, b: Vec3Like) | Dot product |
Vec3.cross | (a: Vec3Like, b: Vec3Like) | Cross product |
Vec3.lerp | (a: Vec3Like, b: Vec3Like, t: number) | Linear interpolation (t=0 returns a, t=1 returns b) |
Vec3.length | (v: Vec3Like) | Vector length/magnitude |
const a = Vec3.of(0, 64, 0);const b = Vec3.of(100, 70, 50);
const mid = Vec3.lerp(a, b, 0.5); // Midpointconst dir = Vec3.direction(a, b); // Unit direction from a to bconst dist = Vec3.distance(a, b); // Distance between pointsconst offset = Vec3.add(a, [0, 10, 0]); // 10 blocks above aconst scaled = Vec3.scale(dir, 5); // 5 blocks in directionInstance Methods
Section titled “Instance Methods”Vec3Instance objects (returned by Vec3.of() and all static methods) have these methods:
| Method | Signature | Returns | Description |
|---|---|---|---|
add | (other: Vec3Like) | Vec3Instance | Add another vector |
subtract | (other: Vec3Like) | Vec3Instance | Subtract another vector |
scale | (scalar: number) | Vec3Instance | Scale by a number |
normalize | () | Vec3Instance | Return unit vector |
distanceTo | (other: Vec3Like) | number | Distance to another point |
distanceToSqr | (other: Vec3Like) | number | Squared distance to another point |
length | () | number | Vector magnitude |
dot | (other: Vec3Like) | number | Dot product |
cross | (other: Vec3Like) | Vec3Instance | Cross product |
lerp | (other: Vec3Like, t: number) | Vec3Instance | Interpolate toward another vector |
Instance properties: x, y, z (all numbers, read-only).
const pos = Vec3.of(10, 65, 20);
const moved = pos.add([5, 0, 5]); // (15, 65, 25)const dist = pos.distanceTo([100, 65, 100]); // Distance as a numberconst dir = pos.subtract([0, 65, 0]).normalize(); // Direction from origin at y=65const half = pos.scale(0.5); // (5, 32.5, 10)Practical Vec3 Examples
Section titled “Practical Vec3 Examples”Teleport player 5 blocks in the direction they are looking:
Events.on('useItem', (player, hand, stack, level) => { const p = wrapPlayer(player); const target = p.pos.add(p.lookAngle.scale(5)); p.teleport(target.x, target.y, target.z);});Check if a player is within 10 blocks of a point:
const shrine = Vec3.of(500, 72, -300);
Events.on('serverTick', (server) => { // Only check every 20 ticks (1 second) if (server.getTickCount() % 20 !== 0) return;
server.getPlayerList().getPlayers().forEach((player) => { const p = wrapPlayer(player); if (p.pos.distanceTo(shrine) < 10) { p.sendActionBar('<light_purple>You feel a warm presence...'); } });});Java Interop
Section titled “Java Interop”The Java.type() function gives you direct access to Java classes from within scripts. This is the escape hatch for anything not covered by the built-in helpers.
Importing Classes
Section titled “Importing Classes”const BlockPos = Java.type('net.minecraft.core.BlockPos');const ResourceLocation = Java.type('net.minecraft.resources.ResourceLocation');const BuiltInRegistries = Java.type('net.minecraft.core.registries.BuiltInRegistries');const AABB = Java.type('net.minecraft.world.phys.AABB');const MobEffectInstance = Java.type('net.minecraft.world.effect.MobEffectInstance');const Component = Java.type('net.minecraft.network.chat.Component');Common Java Classes
Section titled “Common Java Classes”| Class | Import Path | Use Case |
|---|---|---|
BlockPos | net.minecraft.core.BlockPos | Block coordinate positions |
ResourceLocation | net.minecraft.resources.ResourceLocation | Registry identifiers |
BuiltInRegistries | net.minecraft.core.registries.BuiltInRegistries | Access all registries |
AABB | net.minecraft.world.phys.AABB | Axis-aligned bounding boxes |
MobEffectInstance | net.minecraft.world.effect.MobEffectInstance | Effect application |
Component | net.minecraft.network.chat.Component | Chat/text components |
ItemStack | net.minecraft.world.item.ItemStack | Item stack manipulation |
CompoundTag | net.minecraft.nbt.CompoundTag | NBT data |
Working with Java Collections
Section titled “Working with Java Collections”Java collections do not have JavaScript array methods. Use .size() and .get(i) to iterate:
const players = Server.getPlayerList().getPlayers();
// Iterate using size/getfor (let i = 0; i < players.size(); i++) { const player = players.get(i); wrapPlayer(player).sendMessage('<gray>Announcement: Server restart in 5 minutes');}Creating Java Objects
Section titled “Creating Java Objects”const BlockPos = Java.type('net.minecraft.core.BlockPos');const pos = new BlockPos(100, 65, 200);
const AABB = Java.type('net.minecraft.world.phys.AABB');const box = new AABB(0, 0, 0, 100, 100, 100);
// Find entities in a bounding boxconst level = Server.overworld();const entities = level.getEntities(null, box);Logger
Section titled “Logger”The Logger global provides structured logging that writes to the server console with the [Ceremony] prefix.
Methods
Section titled “Methods”| Method | Signature | Description |
|---|---|---|
Logger.info | (message: string, ...args: any) | Informational message |
Logger.warn | (message: string, ...args: any) | Warning message |
Logger.error | (message: string, ...args: any) | Error message |
Logger.debug | (message: string, ...args: any) | Debug message (only visible with debug logging enabled) |
All methods support {} placeholders that are replaced by the additional arguments in order:
Logger.info('Player {} joined from dimension {}', player.getName().getString(), 'overworld');// Output: [Ceremony] Player Steve joined from dimension overworld
Logger.warn('Low TPS detected: {}', server.getAverageTickTime());Logger.error('Failed to load data for player {}', uuid);Logger.debug('Tick count: {}, entities loaded: {}', tickCount, entityCount);State is a global key-value store shared across all scripts. It lives in memory for the duration of the server session and is useful for cross-script communication and runtime flags.
Methods
Section titled “Methods”| Method | Signature | Returns | Description |
|---|---|---|---|
State.get | (key: string) | any | Get a value (returns undefined if not set) |
State.set | (key: string, value: any) | void | Set a value |
State.has | (key: string) | boolean | Check if a key exists |
State.remove | (key: string) | void | Delete a key |
State.keys | () | string[] | Get all stored keys |
// Script A: Set a global flagState.set('event_active', true);State.set('event_name', 'Double XP Weekend');State.set('event_multiplier', 2);
// Script B: Read the flagif (State.has('event_active') && State.get('event_active')) { const multiplier = State.get('event_multiplier'); Logger.info('Event active: {} ({}x)', State.get('event_name'), multiplier);}Cross-Script Communication Example
Section titled “Cross-Script Communication Example”State.set('boss_alive', true);State.set('boss_health', 500);
Events.on('entityDeath', (entity, source, amount) => { if (entity.getName().getString() === 'World Boss') { State.set('boss_alive', false); State.remove('boss_health'); }});
// rewards.jsEvents.on('entityKilledOther', (level, killer, killed) => { if (killed.getName().getString() === 'World Boss' && killer.isPlayer()) { const p = wrapPlayer(killer); p.sendMessage('<gold>You defeated the World Boss!'); p.giveItem('minecraft:nether_star', 1); }});
// announcer.jslet lastAnnounced = false;Events.on('serverTick', (server) => { if (server.getTickCount() % 200 !== 0) return;
const alive = State.get('boss_alive'); if (alive && !lastAnnounced) { // Announce boss is alive server.getPlayerList().getPlayers().forEach((p) => { wrapPlayer(p).sendMessage('<red>A World Boss has appeared!'); }); lastAnnounced = true; } else if (!alive) { lastAnnounced = false; }});Registry Globals
Section titled “Registry Globals”Ceremony pre-wraps common Minecraft registries as global objects. These give you direct access to registry entries by name, avoiding the need to manually look up ResourceLocation keys.
Available Registries
Section titled “Available Registries”| Global | Description | Example Values |
|---|---|---|
ParticleTypes | Particle type registry | ParticleTypes.FLAME, ParticleTypes.END_ROD, ParticleTypes.HEART |
SoundEvents | Sound event registry | SoundEvents.ENTITY_PLAYER_LEVELUP, SoundEvents.BLOCK_ANVIL_LAND |
Items | Item registry | Items.DIAMOND, Items.IRON_SWORD, Items.GOLDEN_APPLE |
Blocks | Block registry | Blocks.STONE, Blocks.DIAMOND_ORE, Blocks.OBSIDIAN |
MobEffects | Mob effect (potion) registry | MobEffects.SPEED, MobEffects.STRENGTH, MobEffects.NIGHT_VISION |
EntityTypes | Entity type registry | EntityTypes.ZOMBIE, EntityTypes.ARMOR_STAND, EntityTypes.CREEPER |
Using Registries
Section titled “Using Registries”// Check if a broken block is diamond oreEvents.on('blockBreak', (player, pos, state, level) => { if (state.getBlock() === Blocks.DIAMOND_ORE) { const p = wrapPlayer(player); p.sendMessage('<aqua>You found diamonds!'); p.playSound('minecraft:entity.player.levelup'); }});
// Spawn particles at a locationconst spawnParticles = (level, pos, particleType, count) => { level.sendParticles( particleType, pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5, count, 0.3, 0.3, 0.3, // spread 0.01 // speed );};
Events.on('useBlock', (player, pos, hand, hitResult, level) => { spawnParticles(level, pos, ParticleTypes.FLAME, 20);});Registry Naming Convention
Section titled “Registry Naming Convention”Registry keys use UPPER_SNAKE_CASE in the global objects. The names correspond to Minecraft’s internal names:
| Minecraft ID | Registry Global |
|---|---|
minecraft:diamond | Items.DIAMOND |
minecraft:stone | Blocks.STONE |
minecraft:speed | MobEffects.SPEED |
minecraft:zombie | EntityTypes.ZOMBIE |
minecraft:entity.player.levelup | SoundEvents.ENTITY_PLAYER_LEVELUP |
minecraft:flame | ParticleTypes.FLAME |
Potions
Section titled “Potions”The Potions registry provides access to potion types for use with brewing and tipped arrows.
| Constant | Description |
|---|---|
Potions.HEALING | Instant Health potion |
Potions.STRONG_HEALING | Instant Health II |
Potions.HARMING | Instant Damage potion |
Potions.POISON | Poison potion |
Potions.REGENERATION | Regeneration potion |
Potions.STRENGTH | Strength potion |
Potions.SPEED | Speed potion |
Potions.LONG_SPEED | Speed (extended) |
Potions.STRONG_SPEED | Speed II |
Potions.NIGHT_VISION | Night Vision potion |
Potions.INVISIBILITY | Invisibility potion |
Potions.FIRE_RESISTANCE | Fire Resistance potion |
Potions.WATER_BREATHING | Water Breathing potion |
Potions.SLOW_FALLING | Slow Falling potion |
Potions.TURTLE_MASTER | Turtle Master potion |
// Example: check what potion type a tipped arrow hasconst potionType = Potions.HEALING;Logger.info('Potion: ' + potionType);Attributes
Section titled “Attributes”The Attributes registry provides access to entity attribute types (health, speed, damage, etc.) for use with attribute modifiers.
| Constant | Description |
|---|---|
Attributes.MAX_HEALTH | Maximum health (default 20) |
Attributes.MOVEMENT_SPEED | Movement speed (default 0.1) |
Attributes.ATTACK_DAMAGE | Attack damage (default 1.0) |
Attributes.ATTACK_SPEED | Attack speed (default 4.0) |
Attributes.ARMOR | Armor value |
Attributes.ARMOR_TOUGHNESS | Armor toughness |
Attributes.KNOCKBACK_RESISTANCE | Knockback resistance (0-1) |
Attributes.LUCK | Luck (affects loot tables) |
Attributes.FOLLOW_RANGE | Mob follow range |
Attributes.FLYING_SPEED | Flying speed (for flying mobs) |
Attributes.SPAWN_REINFORCEMENTS | Zombie reinforcement chance |
// Example: temporarily boost a player's max healthEvents.on('playerJoin', (player) => { const p = wrapPlayer(player); const attr = player.getAttribute(Attributes.MAX_HEALTH); Logger.info(p.name + ' max health: ' + attr.getValue());});Other Globals
Section titled “Other Globals”These globals are always available in Ceremony scripts.
Server / server
Section titled “Server / server”The MinecraftServer instance. Use it to access player lists, worlds, execute commands from the server console, and more.
// Get all online playersconst players = Server.getPlayerList().getPlayers();
// Get the overworldconst overworld = Server.overworld();
// Execute a command as the serverServer.getCommands().getDispatcher().execute( 'say Hello from Ceremony!', Server.createCommandSourceStack());
// Get current tick countconst tick = Server.getTickCount();CeremonyAPI / Ceremony
Section titled “CeremonyAPI / Ceremony”The Ceremony plugin API. Provides access to Ceremony-specific features like regions, displays, HUD, and more.
// Access the Ceremony APIconst api = CeremonyAPI;
// Example: work with regions, displays, etc.Logger.info('Ceremony API version: {}', Ceremony.getVersion());context / ctx
Section titled “context / ctx”The MoLang context object. Provides access to MoLang query, variable, temp, array, and math systems for integration with Journey’s MoLang-based features.
| Property | Description |
|---|---|
context.query / ctx.query | MoLang query functions |
context.variable / ctx.variable | MoLang variables |
context.temp / ctx.temp | MoLang temporary storage |
context.array / ctx.array | MoLang array access |
context.math / ctx.math | MoLang math functions |
// Read a MoLang variableconst level = ctx.query.player_level;
// Set a temp variable for MoLang expressionsctx.temp.custom_value = 42;Combined Example
Section titled “Combined Example”Here is a complete script that uses Vec3, Logger, State, Java interop, and registries together to create a “sacred grove” area that heals players, spawns particles, and tracks visitors.
const groveCenter = Vec3.of(250, 68, -100);const groveRadius = 15;
State.set('grove_visitors', 0);
Events.on('serverTick', (server) => { if (server.getTickCount() % 40 !== 0) return; // Every 2 seconds
const overworld = Server.overworld(); const players = server.getPlayerList().getPlayers();
for (let i = 0; i < players.size(); i++) { const raw = players.get(i); const p = wrapPlayer(raw); const dist = p.pos.distanceTo(groveCenter);
if (dist < groveRadius) { // Heal the player p.addEffect('minecraft:regeneration', { duration: 60, amplifier: 0, visible: false });
// Spawn particles around them overworld.sendParticles( ParticleTypes.HAPPY_VILLAGER, p.pos.x, p.pos.y + 1, p.pos.z, 5, 1.0, 0.5, 1.0, 0.01 );
// Track unique visitors if (!p.data.getBoolean('visited_grove')) { p.data.set('visited_grove', true); State.set('grove_visitors', State.get('grove_visitors') + 1); p.sendMessage('<green>You discovered the Sacred Grove!'); p.playSound('minecraft:block.amethyst_block.chime', { pitch: 1.5 }); Logger.info('{} discovered the Sacred Grove (total visitors: {})', p.name, State.get('grove_visitors')); } } }});- Use
Vec3.distanceSqinstead ofVec3.distancewhen you only need to compare distances — it avoids the square root calculation and is faster. - Registry globals are read-only lookups. You cannot add or modify registry entries at runtime.
Stateis great for runtime flags, but remember it resets on server restart. Use PlayerData for anything that needs to persist.- Keep
Java.type()imports at the top of your script for readability, similar to import statements in other languages. - The
Serverglobal is not available during script loading — it is set once the server has started. Use theserverStartedevent if you need to run initialization logic that depends on it.
Related
Section titled “Related”- Events Reference — All available events and callbacks
- Player Wrapper — Player interface, data, and methods
- MoLang Reference — MoLang expressions used in Journey
- Ceremony Integration — Ceremony setup and configuration