Skip to content

React to game events ​

MyHUD can tell your script when something happens in the game: the match goes live, a round ends, the bomb is planted, the half ends or the map ends. Your script can then send a command, change an OBS scene, post a message, and so on.

The events come through the WebSocket connection. HTTP cannot receive them.

Which events exist ​

EventWhen
match_liveThe warmup ends and the match starts.
round_endA round ends.
bomb_plantedThe bomb is planted.
half_timeThe half-time break starts.
map_endThe map ends.

Each event contains the current scoreboard:

json
{
  "type": "event",
  "name": "round_end",
  "data": {
    "map": "de_mirage",
    "round": 14,
    "scoreCT": 8,
    "scoreT": 6,
    "teamCT": "Vitality",
    "teamT": "NAVI",
    "winner": "CT"
  }
}

winner is only on round_end and map_end. It is CT, T, or null for a draw.

MyHUD reads these events from the game data (GSI) of CS2. CS2 must send its data to MyHUD, like for the HUD.

TIP

If your script connects in the middle of a match, MyHUD does not send the events that already happened. The first event comes with the next change.

Subscribe to the events ​

Game events are not sent by default. After you connect, send a subscribe message:

json
{ "type": "subscribe", "channels": ["game"] }

MyHUD answers:

json
{ "type": "subscribed", "channels": ["game"] }

You can also listen to other channels. See WebSocket API.

Example: show the map recap at the end of a map ​

This script waits for map_end, then opens the map recap scene. It sends the command on the same connection, with a trigger message.

  • Python: install the websockets package first: pip install websockets.
  • TypeScript: Node.js 22 or later has WebSocket built in. No package needed.
python
import asyncio
import json

import websockets

URL = "ws://127.0.0.1:44555"


async def main():
    # Connects again after each disconnection (MyHUD restarted, settings changed...).
    async for ws in websockets.connect(URL):
        try:
            await ws.send(json.dumps({"type": "subscribe", "channels": ["game"]}))

            async for raw in ws:
                msg = json.loads(raw)

                if msg["type"] == "event" and msg["name"] == "round_end":
                    d = msg["data"]
                    print(f"Round {d['round']}: {d['teamCT']} {d['scoreCT']} - {d['scoreT']} {d['teamT']}")

                elif msg["type"] == "event" and msg["name"] == "map_end":
                    print("Map over, showing the recap")
                    await ws.send(json.dumps({
                        "type": "trigger",
                        "action": "show_sen_scene",
                        "payload": {"scene": "mapRecap"},
                        "correlationId": "recap",
                    }))

                elif msg["type"] == "ack" and not msg["ok"]:
                    print("Command failed:", msg.get("code"), msg.get("error"))
        except websockets.ConnectionClosed:
            continue


asyncio.run(main())
ts
const URL_WS = 'ws://127.0.0.1:44555';

type Scoreboard = {
  map: string | null;
  round: number | null;
  scoreCT: number;
  scoreT: number;
  teamCT: string | null;
  teamT: string | null;
  winner?: 'CT' | 'T' | null;
};

function connect() {
  const ws = new WebSocket(URL_WS);

  ws.addEventListener('open', () => {
    ws.send(JSON.stringify({ type: 'subscribe', channels: ['game'] }));
  });

  ws.addEventListener('message', (e) => {
    const msg = JSON.parse(String(e.data));

    if (msg.type === 'event' && msg.name === 'round_end') {
      const d = msg.data as Scoreboard;
      console.log(`Round ${d.round}: ${d.teamCT} ${d.scoreCT} - ${d.scoreT} ${d.teamT}`);
    } else if (msg.type === 'event' && msg.name === 'map_end') {
      console.log('Map over, showing the recap');
      ws.send(
        JSON.stringify({
          type: 'trigger',
          action: 'show_sen_scene',
          payload: { scene: 'mapRecap' },
          correlationId: 'recap',
        }),
      );
    } else if (msg.type === 'ack' && !msg.ok) {
      console.log('Command failed:', msg.code, msg.error);
    }
  });

  // Connects again after each disconnection (MyHUD restarted, settings changed...).
  ws.addEventListener('close', () => setTimeout(connect, 3000));
}

connect();

To use it from another device, add the token to the URL: ws://192.168.1.20:44555/?token=<token>. See Control from another device.

Reconnect ​

MyHUD closes all connections when it restarts, or when you change the automation settings. Your script must connect again, then send subscribe again. The examples above do it.