Skip to content

JavaScript API reference

The editor’s API panel is the authoritative signature and packet-field reference for the selected Minecraft version. The namespaces below exist in all supported families; underlying Java objects and generated packet names remain version-specific.

ExportMethods and purpose
MinecraftVersionSelected family identifier.
EventType, EventsTyped constants; on, onPacket; synchronous ordered event registration.
Clientraw, in-game state, server address, main-thread scheduling, macro/Mint logging, FPS, screen/mouse/window dimensions, FOV, gamma, sensitivity, render distance, perspective, version.
Timersafter, every, clear, pending.
PlayerIdentity, position/eye/rotation, health/hunger/armor/XP, state flags, velocity, held/off-hand/armor/effects, ping/game mode, target wrappers, chat, position/look/flying controls.
ItemRaw stack inspection and summary: ID/name/count/damage/durability metadata.
InputHold/release named movement, mouse, inventory, and keyboard inputs; query isDown.
TargetCrosshair hit type, block/hit/place coordinates, side, block/entity, distance.
InteractionAttack/use/place, click/quick-move/move/swap/drop/equip slots, close screen, mine at a position, tap a key.
Chatprint a client-only line or send a normal server chat message.
PacketsSend a packet; class/chat lookup; cached field, fieldNames, and fields.
PathfindergoTo(x,y,z,allowFly?,sprint?,showPath?), follow(player,distance?,sprint?), stop, isActive.
ReplaySelect/start/stop/pause/resume playback, query playing state, mark out-of-sync, queue the replay that plays instead of the next repeat, and import/load/unload a replay so it can play at all.
RenderWorld block/entity boxes, tracers, lines, nametags; overlay lines/rectangles/text and overlay dimensions. Call in the matching render event every frame.
PhantomClient-side collision boxes with no block behind them: add, remove, has, clear, count, plus the on/off and override switches.
FilesSandboxed per-macro read, write, append, exists, remove, list, size, folder, readJson, writeJson. Names cannot escape the macro folder.
MinecraftFluent root: player, world, inventory, entities, raw client, server address, logging.
WorldTime/weather/dimension/difficulty/counts, block/biome/light/top-Y/chunk queries, client-side block display, entity/player searches.
InventoryPlayer and open-screen slots/items, selection, counts/searches, empties, close screen. Normal player inventory is not reported as an open container.
EntitiesAll/nearby/player lists and nearest/text/name/id lookups.
MintPosCoordinate access, offsets/directions/distance, block wrapper.
MintBlockPosition/name/ID/air/test, mine, client-side showAs, offsets, raw block.
MintItemEmpty/name/ID/count/damage/durability/NBT/lore/enchantments and raw stack.
MintEntityIdentity/type/position/rotation/velocity/health/state/test/look, player inventory/held item, raw entity.
ScoreboardRead title/lines/entries/scores/teams/objectives; client-side title/line/render controls.
TabListNames/entries/ping/game mode/header/footer plus header/footer controls.
TitleTitle/subtitle timing, action bar, clear.
Soundplay, playAt, and version-specific ids. 1.8.9 IDs differ from modern IDs.
Particlespawn, velocity overload, spawnMany, and version-specific ids.
Httprequest, get, post, getJson, postJson; responses contain status/headers/text/json.
Workersrun(exportedFunctionName, copiedData) for CPU work in a restricted context.
MainThreadrun(handler) and await(completionStage) for explicit safe resumption.

Pathfinder

Walks or flies the player to a position by holding the movement keys, the way a player would. It never mines, places blocks, or touches your inventory.

Pathfinder.goTo(120.5, 70, -32.5); // fly if you can, otherwise walk
Pathfinder.goTo(120.5, 70, -32.5, false); // always walk
Pathfinder.follow("FriendName"); // stay 3 blocks behind
Pathfinder.follow("", 5); // follow whoever is nearest, 5 blocks behind
if (Pathfinder.isActive()) Pathfinder.stop();
Method
goTo(x, y, z, allowFly?, sprint?, showPath?)Go to a position.
follow(player, distance?, sprint?)Follow a player, re-routing as they move. A blank name follows whoever is nearest.
stop()Stop the route your macro started.
isActive()Is a route running?

Options:

  • allowFly — false by default: flight is opt-in. Set true to allow it. Ignored if you cannot fly, so asking for it in survival just walks. follow takes no flight argument and always walks.
  • sprint — true by default. Sprints on long straight runs.
  • showPath — true by default. Draws the route in the world.

follow’s distance is how far behind to stay, 3 blocks by default.

Only one route runs at a time. goTo returns false only when it cannot start at all (no world); a destination it cannot reach still returns true and gives up by itself, so use isActive() to tell when it has finished. Calling goTo with the same destination again carries on rather than starting over, so it is safe to call every tick.

Phantom blocks

Collision boxes at coordinates Mint holds, with no block behind them. Nothing is placed in the world and nothing is sent to the server — the block there is still air, and everyone else sees air.

Phantom.setEnabled(true);
Phantom.add(120, 70, -32); // false if one is already there
Phantom.has(120, 70, -32); // true
Phantom.remove(120, 70, -32);
Phantom.clear();

A phantom block is a wall, never a floor:

You are…Result
walking into itstopped, exactly as a block would stop you
flying or jumping up into it from belowstopped at its underside
falling onto it from aboveyou drop straight through — it is not there
standing beside it, trying to step upno step-up; it has no top to stand on
looking at or clicking itthe crosshair misses; the click lands on whatever is really behind it
Method
add(x, y, z)Add one. false when one is already there. Coordinates are floored to the block.
remove(x, y, z)Remove one. false when there was none.
has(x, y, z)Is one there?
clear()Remove all of them.
count()How many there are.
enabled() / setEnabled(v)Whether they collide and are drawn. The same switch as the one in Settings.
override() / setOverride(v)Whether one that landed on a real block is drawn as that block. See below.

They only affect you and whatever you are riding, and they are drawn as a 70%-transparent gold block with the Mint logo on every face. Once you are partly inside one it stops pushing you at all, so a fall through is a single clean drop rather than a fight with the collision resolver.

The coordinates last until you close the game and are never written to disk. They are kept across a world change, so the same coordinates are the same phantom blocks wherever you are — out of render distance they simply stop drawing. A macro that wants a set to survive a restart should keep it in Files and re-add it on start.

They are shared client-wide rather than owned per macro: two macros adding the same coordinate are adding the same block, and clear() clears everyone’s — prefer remove when you only mean to tidy up after yourself. Settings → Phantom blocks carries the same switches plus a placement mode for putting them down by hand.

Use the real block’s look

By default every phantom block is drawn as a see-through gold block. With setOverride(true), one that landed on a real block is drawn as that block instead: its own model, its own textures and its own tint, at the same transparency, with the same logo on every face. A phantom block on stone becomes see-through stone; on oak planks, see-through oak planks; on leaves it even keeps its biome tint.

Blocks with no block model of their own — chests, water, anything drawn as a block entity — have nothing to borrow, so those keep the gold block rather than drawing nothing at all.

The logo always sits on the faces of the full cube, whatever shape the borrowed model is, so on a slab it marks out the collision volume rather than the slab.

Override is a single switch for all of them, not a per-block flag, and it is saved.

Replay queue

Replay.start stops whatever is playing and starts something else. Replay.queue does not: it says which replay should play instead of the next repeat of the current one, and can be called at any time, including in the middle of a run.

Replay.queue("replay-id"); // false when the replay is not yours, or not loaded
Replay.queued(); // "replay-id" until it is consumed, otherwise ""
Replay.clearQueue(); // changed your mind — the current clip keeps looping
Method
queue(replayId)Play that replay instead of repeating this one. "" clears the queue.
queued()The queued replay’s id, or "".
clearQueue()Forget the queued replay.

The switch happens where the loop would have started the same clip again — after one run ends and before the next begins — so Loop replay has to be on for a queue to ever be reached. That moment is the only point where changing clips is free: the queued replay then starts as an ordinary play, with the position and camera locks, the drift syncs, the entity/area/inventory checks and the smooth camera pan onto its first look all arming against the new clip. Stopping and starting to change clips skips all of those in between.

The loop count carries across the switch. Loop amount is a budget for the loop, not for a clip: with three runs asked for and a clip queued during the first, you get one run of the first clip and two of the queued one, and then the loop ends. Set Loop amount to 0 for a rotation that keeps going.

Only a loaded replay can be queued. queue does not download: it is refused for a replay whose payload is not in memory, exactly as start is, so what you queue is always something that can play. Replay.ensureLoadedAsync(id) is how a macro fixes that for itself. Queueing the clip that is already playing does nothing.

A queue outlives a stop: it is consumed by the next play, wherever that play comes from — the loop, the Play key, or Replay.start(). That includes Replay.start("some-other-id"), which will play the queued clip, so call clearQueue() first if you mean to override it.

Getting a replay loaded

Both start and queue need the replay’s payload in memory. A macro can put it there itself instead of asking the user to open the Replays tab.

if (await Replay.ensureLoadedAsync(id)) Replay.start(id);

ensureLoadedAsync does whichever steps are missing: it claims the replay for your account if it is not there, downloads the payload if it is not in memory, and resolves to whether the replay can be played now.

Method
ensureLoadedAsync(replayId)Promise<boolean>. Claim it if missing, download it if not loaded, resolves true when it can play.
isLoaded(replayId)Whether the payload is in memory. Instant.
unload(replayId)Free the payload. Refused for the replay that is playing.

The fetch happens off the client thread and the Promise settles on the next main-thread drain, so awaiting it costs ticks rather than frames — awaiting it inside a tick handler is fine. Asking again while the first fetch is still out joins that fetch instead of starting a second, and a replay that is already loaded resolves true with no request at all. Claiming a replay your account does not have is not available on free accounts.

Event payloads

  • Tick: phase.
  • Render: phase plus frame timing/camera fields supplied by the version wrapper.
  • Key: named key/code and pressed state.
  • Interaction: action-specific target and cancellable state.
  • Packet: real packet, class, direction, lazy fields, cancellation.
  • Chat: packet payload plus message and cancellation.
  • Replay: type, phase, replay ID, cancellation for pre transitions.

Generated packet types

Each API declaration includes unions for every known inbound/outbound packet and an interface for its readable fields. Use Events.onPacket(PacketType.SomePacket, handler) or a typed packet event when the editor offers it. Unknown/modded packets remain accessible through the generic packet event and reflection helpers.

Globals and aliases

All namespaces are importable from mint:api and declared globally for short scripts. on, onPacket, packetField, packetFieldNames, packetFields, runOnMainThread, and awaitFuture are convenience functions. Standard console.log/warn/error/debug writes to the macro runtime log.