Shockless Plugin API
This page lists every API exposed to user plugins by
src/renderer/userPluginHost.ts. Plugins run in a
restricted renderer Worker and use grouped APIs for game state,
packets, runtime control, avatar actions, furniture, typed domain
actions, social actions, storage, and session data.
Quickstart
Plugin Entry
Each user plugin exports activate(api). Return a disposer when the plugin subscribes to events.
export async function activate(api) {
const { avatar, log, room, storage, subscriptions } = api;
const cleanup = subscriptions.create();
const enabled = await storage.get("enabled", true);
if (enabled) await avatar.wave();
cleanup.add(room.onReady((event) => {
log.info(`Ready in ${event.room?.name ?? "unknown"}`);
}));
return cleanup.dispose;
}
Manifest
Permissions gate API calls and event delivery. Only request the permissions your plugin uses.
{
"id": "room-tools",
"name": "Room Tools",
"version": "1.0.0",
"entry": "plugin.js",
"icon": "wrench",
"category": "room",
"permissions": ["ui.panel", "events.room", "engine.snapshot"],
"managedRuntime": {
"clientRights": []
},
"surfaces": [
{
"id": "panel",
"kind": "panel",
"label": "Room Tools",
"enabledByDefault": true,
"summary": "Room helper controls."
}
]
}
Icons
Use these manifest icon keys in shockless.plugin.json.
Unknown values are accepted but render as the fallback alert icon.
Permissions
Common Shapes
Client Targeting
Most relay-backed action APIs accept options.clientId. If omitted, the selected client is used. Snapshot selectors and direct runtime control currently need the selected visible runtime.
await avatar.wave({ clientId: 2 });
await social.addUser("FriendName", { clientId: 3 });
await engine.getSnapshot(2);
Item Selectors
Furniture helpers accept numeric ids, live item payloads, or selector objects. Text selectors search id, key, name, className, ownerName, query, text, and metadata title.
await furni.findItems("chair");
await furni.findItem({ className: "ads_fish_area", exact: true });
await furni.pickupItem({ id: 12345, kind: "floor" });
Wall Locations
Wall movement needs wall and local coordinates plus orientation. You can pass absolute coordinates or deltas when a parsed wall item already has a base location.
await furni.moveWallItem("poster", {
deltaX: 1,
deltaY: 0,
orientation: "r"
});
Packet Filters
Packet hooks filter by direction plus optional header or packetName. Unknown headers must be shown as UNKNOWN_HEADER, not guessed.
const off = packets.on("server", { packetName: "USERS" }, (packet) => {
log.info(packet.plainText);
return packet.allow();
});
API Groups
Events
Plugin Recipes
These are realistic plugin ideas that can be built from the APIs on this page. Each row names the main APIs, permissions, and a starter shape so authors can see how the pieces fit together.
Desktop Bridge
User plugins should use the restricted Worker API above. These
window.habbpyV4 methods are listed for maintainers because
the Worker API is built on top of them.
Current Limits
| Limit | Meaning |
|---|---|
console.registerCommand() | Reserved for the command registry phase. Manifest command declarations can be persisted, but runtime registration is not active. |
ui.registerSurface() / ui.updateSurface() | Implemented for host-rendered schema layouts. ui.registerPanel() is a compatibility alias, not a React/HTML panel hook. |
| Schema controls | Supported controls include headers, text, notices, sections, buttons, buttonGrid, toggles, inputs, selects, keybinds, key/value rows, logs, and selectable tables with rowKey, selectedRowKey, rowAction, and maxRows. |
packets.send() | Implemented for client-to-server Shockwave packets through the validated builder. Known action helpers remain preferred for normal gameplay actions. |
| Selected visible runtime | Stage clicks, Navigator control, window clicks, room entry, client rights, and selector-based room object reads currently target the selected visible runtime. Chat helpers can route to target relay sessions for packet-backed modes. |
| Security boundary | User plugins do not receive Node, Electron, filesystem, account credentials, webhook values, or raw local test files. |
| Known actions | Use typed domain APIs for known actions. Use packet observation for discovery or local events when no first-class event exists yet. |