$ magic imports
You are a developer, and therefore lazy in one way or another. You will be reaching for Java classes
constantly, whether that is the Bukkit Material enum or your own plugin’s UserManager, and typing
Script.loadClass('org.bukkit.Material') every time gets old.
The $ global resolves a class by its simple name by searching a configured list of packages.
const buildableBlocks = [
$.Material.OAK_PLANKS,
$.Material.STONE_BRICKS,
$.Material.GLASS_PANE,
];
if (!(sender instanceof $.Player)) {
sender.sendRichMessage('<red>This command can only be run by a player.</red>');
return;
}
registerListener($.PlayerJoinEvent, (event) => { /* ... */ });
Configuring the search path
class-searchcontext.yml in plugins/PixelScript lists the packages $ searches:
search-packages:
- 'org.bukkit'
- 'com.destroystokyo.paper'
- 'org.spigotmc'
Add your own framework or plugin package here and $.UserManager starts working. See
Configuration.
Performance
The first lookup of a given name walks the search path, which costs real time proportional to how many packages you have listed. Every lookup after that is a cached map hit.
That is fast, but it is never as fast as a plain const holding the class. So:
- Use
$for enums, event classes, and one-offinstanceofchecks in code paths that can spare a map lookup. - Use
Script.loadClassin hot loops, and for anything outside your search path.
Reaching for $ inside a per-tick timer that runs for every online player is the one case where this
actually shows up in a profile.
The recommended alternative
For anything you use across many files, the cleanest option is a small module that exports the classes once:
// utils/bukkit-types.js
export const Material = Script.loadClass('org.bukkit.Material');
export const ItemStack = Script.loadClass('org.bukkit.inventory.ItemStack');
export const Player = Script.loadClass('org.bukkit.entity.Player');
import { Material, ItemStack } from '@/utils/bukkit-types';
You get one resolution for the whole runtime, real import statements your IDE can follow, and a single place to change when a class moves. See import and export.
Failure behaviour
If $ cannot find a class it logs Class not found: <name> and returns null. It does not throw, so a
typo shows up as a confusing TypeError further down rather than at the point of the mistake. When
something is mysteriously undefined, check the console first.