Skip to content

ScriptingEvents

Two ways to subscribe. They are the same mechanism underneath, so priorities, unsubscription and error handling behave identically whichever you use.

By name. A top-level function called onSomething is subscribed to something:

function onChat(e) {
    if (e.message.indexOf('gg') === 0) chat.print('gg');
}

Explicitly, when you need a priority, a conditional subscription, two handlers on one event, or the ability to unsubscribe:

var handler = function (e) { /* … */ };
events.on('chat', handler, events.HIGHEST);
events.off('chat', handler);          // must be the same function object
events.once('gameStart', function (e) { /* … */ });

Priorities: events.HIGHEST (2), HIGH, NORMAL (0), LOW, LOWEST. Higher runs first. Handlers at the same priority run in registration order.

Cancelling is e.cancel() (or e.cancelled = true), never a return value. A handler's return value is ignored. e.cancellable says whether cancelling this event does anything.

events.list() returns every event name this build can fire. It is the authority, not this page. An unknown name passed to events.on throws, with your file and line.

The catalogue

Every event below is wired to a real host hook. If it is listed, it fires.

name payload cancels backed by
tick no the client tick (20/s)
renderWorld partialTicks no the world render pass
renderHud width, height no the HUD render path — see the note below
chat message, formatted; message settable yes incoming chat packets
chatSend message, settable yes the outgoing chat hook
playerChat name, rank, message no a player line parsed from Hypixel chat
worldLoad no the world object changing, detected on the tick
worldUnload no as above
gameStart game, mode, map, source no the sidebar state transition
gameEnd game, outcome no the VICTORY / GAME OVER title
playerJoin name, uuid no a tab-list add
lobbyJoin name, players, maxPlayers, fresh no Hypixel's "X has joined (4/16)!"
partyJoin members, names, size no the party detector
whoRoster names, size no a /who reply
key code, char, key yes¹ the key hook ahead of vanilla's dispatch

¹ key has two possible sources. When the host's key hook is wired, the event is raised in front of everything else and e.cancel() genuinely swallows the press. When it is not, the script system falls back to sampling the keyboard on the tick: the event still fires once per press with the right code, but it cannot cancel and e.char is empty. e.cancellable tells you which you have, and /bitchos script hooks prints it.

renderHud has the same arrangement: it prefers the host's HUD hook and falls back to an invisible HUD element, which works identically except that it stops firing if you turn the HUD module off. /bitchos script hooks says which route is live.

Events that are not here, and why

  • packetIn / packetOut. There is no generic packet hook in this mod. The packet mixin injects into five named handlers and nothing else, so a general "every packet" event would have to be invented rather than wired, and it would silently fire for five packet types out of a hundred and eighty. Cancelling packets is also a good way to flag an anticheat. The honest position is that the hook does not exist, and a documented event that never fires is worse than an absent one.
  • attackEntity, preMotion, playerInput, mouse, guiOpen, entitySpawn. Same reason: no host hook.

If you need one of these, the host needs a mixin for it first. Suggest it.

Rewriting a chat message

Assigning e.message in a chat handler does not edit the packet; the host hook can only cancel. So a rewrite is what it honestly is: the original line is suppressed and your replacement is printed locally instead. The visible cost is that a rewritten line loses the server's hover text and click actions (a rank tooltip, a click-to-accept party invite). Rewriting a plain line costs nothing.

chatSend has no such compromise. The hook sits in front of sendChatMessage, so an assignment genuinely changes what the server receives and e.cancel() genuinely stops it leaving.

function onChatSend(e) {
    if (e.message === 'gg') e.message = 'gg, well played';
}