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
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.
| Parameter | Type | Description |
|---|---|---|
event | string | Event name (game event or custom event) |
callback | (data) => void | Handler function |
Returns: () => void — call to unsubscribe
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.
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.
// 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.
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
| Event | Data | Description |
|---|---|---|
Terminal.NmapScan | NmapScanEvent | Player ran nmap on an IP |
Terminal.SSH.Connected | string (connected server IP) | Player connected via SSH |
Terminal.SSH.Disconnected | string (disconnected server IP) | Player disconnected from SSH |
Terminal.Command | TerminalCommandEvent | Any terminal command executed |
Terminal.Whois | WhoisEvent | Player ran whois |
File Events
| Event | Data | Description |
|---|---|---|
Files.Open | FileOpenEvent | A file was opened |
Files.Transfer | FileTransferEvent | A file was downloaded / transferred |
Files.Deleted | { id: string; name: string } | A file was deleted |
Network Events
| Event | Data | Description |
|---|---|---|
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
| Event | Data | Description |
|---|---|---|
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:
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:
// 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:
// 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:
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");
}
});
}
}