Skip to content

Events

The Events namespace provides access to the game's event system. Listen to in-game events (terminal commands, file operations, network activity), emit events to the game engine, and communicate between mods using custom events.

Required permission: events

Import

typescript
import { Events } from "@hotbunny/hackhub-content-sdk";

Methods

Events.on(event, callback)

Listen to a game event or a custom mod event. Returns an unsubscribe function.

ParameterTypeDescription
eventstringEvent name (game event or custom event)
callback(data) => voidHandler function

Returns: () => void — call to unsubscribe

typescript
const unsub = Events.on("Terminal.NmapScan", (data) => {
    console.log(`Player scanned ${data.ip}`);
});

// Later: stop listening
unsub();

Events.off(event, callback)

Remove a specific event listener by reference.

typescript
function handler(data: any) { /* ... */ }
Events.on("Terminal.NmapScan", handler);
Events.off("Terminal.NmapScan", handler);

Events.emit(event, data?)

Emit an event. Behavior depends on the event name:

  • Known game events (e.g. Terminal.NmapScan, Bank.Transfer) — dispatched to both the game event bus and the custom event bus.
  • Custom/unknown events (e.g. MyMod.BossDefeated) — dispatched only to the custom event bus, enabling cross-mod communication without polluting game internals.
typescript
// Custom event — goes to other mods only
Events.emit("MyMod.BossDefeated", { bossName: "Hydra", reward: 500 });

// Known game event — also triggers game engine listeners
Events.emit("Terminal.NmapScan", { ip: "10.0.0.1" });

Events.register(name)

Register a custom event name for cross-mod communication. Optional but recommended for discoverability.

typescript
Events.register("MyMod.BossDefeated");
Events.register("MyMod.LevelUp");

Game Events

These are built-in events emitted by the game engine. Use them in Events.on() to react to player actions. The SDK's ModEventMap type is the authoritative, fully-typed list of every event and its payload — see Event Map.

Terminal Events

EventDataDescription
Terminal.NmapScanNmapScanEventPlayer ran nmap on an IP
Terminal.SSH.Connectedstring (connected server IP)Player connected via SSH
Terminal.SSH.Disconnectedstring (disconnected server IP)Player disconnected from SSH
Terminal.CommandTerminalCommandEventAny terminal command executed
Terminal.WhoisWhoisEventPlayer ran whois

File Events

EventDataDescription
Files.OpenFileOpenEventA file was opened
Files.TransferFileTransferEventA file was downloaded / transferred
Files.Deleted{ id: string; name: string }A file was deleted

Network Events

EventDataDescription
Network.PortChanges{ ip: string; port: number; active: boolean }Port state changed
Network.UserActivity{ userId: string; online: boolean }User went online/offline
Network.WifiConnected{ ip: string; ssid?: string }Connected to WiFi

WeeChat Events

EventDataDescription
WeeChat.Message{ host: string; username: string; message: any }Message sent in WeeChat

Type-Safe Custom Events

You can extend the ModEventMap interface to get full type safety for your custom events. Use TypeScript's declaration merging:

typescript
declare module "@hotbunny/hackhub-content-sdk" {
    interface ModEventMap {
        "MyMod.BossDefeated": { bossName: string; reward: number };
        "MyMod.LevelUp": { level: number; xp: number };
    }
}

After this declaration, Events.on() and Events.emit() provide full type inference for your custom events:

typescript
// Fully typed — data is { bossName: string; reward: number }
Events.on("MyMod.BossDefeated", (data) => {
    console.log(`${data.bossName} defeated! Reward: $${data.reward}`);
});

// Type error if payload doesn't match
Events.emit("MyMod.LevelUp", { level: 5, xp: 1200 });

You can place the declare module block anywhere in your project (e.g. in a types.d.ts file or at the top of your main index.ts).

Cross-Mod Communication

Mods can communicate by emitting and listening to custom events:

typescript
// Mod A: Register and emit
Events.register("ModA.DataReady");
Events.emit("ModA.DataReady", { items: ["sword", "shield"] });

// Mod B: Listen
Events.on("ModA.DataReady", (data) => {
    console.log("Mod A shared:", data.items);
});

Quest Events (Scoped)

Inside a Quest class, use this.Events.on() instead of the global Events.on(). Scoped listeners are automatically cleaned up when the quest completes or is abandoned.

Register them in OnObjectivesStart() (runs on claim and on every game start), not OnStart() (runs once at claim). Listeners are lost on reload, and only OnObjectivesStart() re-attaches them:

typescript
class MyQuest extends Quest {
    // Runs on claim and on every game start, so listeners survive reloads.
    OnObjectivesStart() {
        this.Events.on("Terminal.NmapScan", (data) => {
            if (data.ip === "192.168.1.50") {
                this.completeObjective("scan");
            }
        });
    }
}

HotBunny Interactive Entertainment Inc.