Addons
For additional details regarding setup and usage, check Addon Guide
While you can think of HUDs as Javascript web apps with game data injected by LHM, Addons are the opposite of that - custom, user generated code designed to run in the server environment, without UI. Addons were created to make internal integrations easier - a simple example would be triggering custom action on your stream in obs, while more advanced example would cover stage integrations, such as triggering LEDs to blink red when bomb is planted, or start fires when it explodes. This interface is designed to be customer-oriented, instead of directed towards the viewer.
It is best to copy example addon from our github to start.
Addons require a simple addon.json file for identification. This should cover simple meta-data, such as author, name, version and (most importantly) entry file, "main"
While we love TypeScript, due to how the sandboxing in LHM works, files must be raw JS, with CJS syntax. For ease of development, we added declaration file, which is included through reference at the top of the example index.js file
For each addon, LHM fills global scope with a few helper functions that are required for lifecycle of the addon. Those functions are onStart
, onClose
, loadConfig
and notify
When user starts an addon, first called is
loadConfig
This is function that runs before addons should perform any action. This helps generating dynamic settins panels. For example, if your Addon wants to somehow influence vMix inputs, and you want to have dropdown selects with those inputs, or basically pre-fill settings with any external data, this is the place to put it.
loadConfig
accepts async function as its only argument. This function must return an array, which should be in the same format as section.inputs part of the panel.json file from the HUDs, as addons do not support sections.
Additionally, loadConfig
argument function's only argument is config's values from the last run. This is useful when rest of the panel is based on some inital conditions - for example, first input might be ip address for the local machine, from which addon will fetch vMix inputs, like in the (Camera Mixer) addon.
Because the loadConfig
callback can be async, it has time to fetch external interfaces to create the settings panel.
After loadConfig
's callback resolves, settings template is sent to LHM for user to edit, and onStart
callback is then called.
onStart
There can only be one instance of calling onStart
in the addon. It accepts async function as an argument, and then passes Argument
object as its parameter:
type OnConfigChange = (config: any) => void;
type OnActionCallback = (
action: string,
callback: (value: string) => void
) => void;
type Argument = {
config: any;
CSGOGSI: CSGOGSI;
DOTAGSI: DOTA2GSI;
close: () => Promise<boolean>;
onConfigChange: (callback: OnConfigChange) => void;
onAction: OnActionCallback;
};
Then, in that callback, you can specify event listeners for any event coming from Dota or CS2. A simple example would be:
CSGOGSI.on("mvp", (player) => {
const current = CSGOGSI.current;
if (!current) return;
const round = current.round?.phase === "over"
? current.map.round
: current.map.round + 1;
fs.writeFileSync(path.join(__dirname, `./round_${round}_mvp.json`), player.steamid, "utf-8");
});
This example should generate files with names like round_5_mvp.json
, which content is SteamID of a player that got MVP point from the Counter-Strike in that specific round. While this example is very simple, you can npm install
other dependencies to the addon, to (for example) send MIDI signals to external devices.
onClose
onClose is responsible for cleaning app all the app. In the most base Addons, all you have to do is remove listeners added to the game event emitters:
onClose(({ CSGOGSI, config }) => {
CSGOGSI.removeAllListeners("bombExplode");
CSGOGSI.removeAllListeners("data");
});
However, if you spin up any servers (whether HTTP or WebSockets), or start any long-running functions, you must finalize everything here.
notify
This function is a small helper function to allow Addon developers to send a notification. Potentially useful to notify user if addon's initial configuration is potentially incorrect.
// Second argument is optional
notify("API credentials are empty!", "error");