Goal: any game or mod can send gameplay events to Hovermate. Hovermate turns them into timeline markers and automatic highlights exactly like built-in game cards. Three transports cover every mod environment: network, file-only and log-only.
1. Connection discovery
Engine writes %LOCALAPPDATA%\Hovermate\Sdk\connection.json while the SDK is enabled (Settings › Clips › Game events SDK, on by default):
{
"version": 1,
"url": "http://local.hovermate.gg/hovermate/v1/events",
"token": "<random, base64url, 32 bytes>",
"inbox": "C:\\Users\\<user>\\AppData\\Local\\Hovermate\\Sdk\\Inbox"
}urlis where events are sent. Read it from this file and use it exactly as written; never hard-code or change the host, port or path. Hovermate currently writeshttp://local.hovermate.gg/hovermate/v1/events; the SDK mock server writes its own test address.- Clients read this file at start-up and again after any
401response. The token may rotate. HOVERMATE_SDK_CONNECTION=<path>overrides the file location (tests, tools, isolated data folders). Clients always take the inbox path from the file'sinboxfield and never derive it themselves.- When the file is missing, Hovermate is not installed or the SDK is off. Clients stay silent and never throw into the game.
2. Transports
2.1 HTTP (mods with networking: C#, C++, Java, Python, JS)
POST {url}; headersAuthorization: Bearer <token>,Content-Type: application/json.- Requests that carry an
Originheader are rejected with403, so browsers cannot post. - Body: one event object, or
{ "events": [ ... ] }with at most 100 events. Maximum body size is 64 KB. - A batch is all-or-nothing. Hovermate validates every event first. If one is invalid, nothing is accepted and the
400body names its position:{ "error": "<code>", "detail": "...", "index": 3 }. For a game that is new in this session,game.namemust appear in the first event of the batch that mentions it. -
Responses:
202accepted;400invalid, with body{ "error": "<code>", "detail": "...", "index": <n, batches only> };401bad or missing token;403the request has anOriginheader;413body too large. A body of up to 1 MB is read and discarded first, so the client sees the status; larger bodies may be refused before they are read, and the connection is closed;429more than 20 events/s per game;405,411,415wrong method, missing length or wrong content type.
- Clients send fire-and-forget from a background worker. They never block the game thread, use timeouts of 250 ms or less, keep a bounded queue (drop oldest) and retry at most once.
2.2 JSONL inbox (mods that can write files but cannot use the network)
- Append UTF-8 lines to
{inbox}\<game.id>.jsonl, one event object per line, no BOM. - No token is needed: the folder belongs to the user.
- Engine tails every
*.jsonlfile in the inbox from its end at start-up. A mod may truncate its file when a session starts.
2.3 Log-line convention (script mods that can only write to the game's own log)
- Any line containing the marker
[HOVERMATE]followed by one JSON event object. Everything before the marker is ignored (timestamps, channel names). - The SDK card has a "Read events from a file" list where the user adds a log path. A
helloevent (see §4) that arrives over another transport can also propose one. Engine reads the file with the existing log-tail adapter. - For games whose script log has a known location, Hovermate watches it automatically while the game runs. The list lives in the game catalog (
sdkLogs), for exampleDocuments\The Witcher 3\scriptslog.txtand the Skyrim/Fallout Papyrus logs. Mods for these games need no user setup beyond enabling the game's script logging.
2.4 Mod-folder event file (sandboxes that can write only inside the mod's own folder)
- Some mod frameworks allow writing only inside the mod's folder, for example Cyber Engine Tweaks Lua mods. Such a mod appends JSONL lines (the format of §2.2) to
hovermate-events.jsonlin its own folder. - The user adds that file in the SDK card's "Read events from a file" list. The mod's README should tell them where it is. Hovermate tails it like an inbox file.
- A mod may also print its own path once as a
[HOVERMATE]log line or send it inhello.files(an array of paths) when another transport is available. Hovermate then offers to add it.
3. Event object
{
"v": 1,
"game": { "id": "com.example.mygame", "name": "My Game", "exe": "MyGame.exe" },
"type": "kill",
"label": "Double kill",
"tags": ["headshot"],
"context": "Act 2 · The City",
"time": "2026-11-09T21:15:03.120Z"
}v— required,1.game.id— required,[a-z0-9._-]{3,64}. Reverse-DNS or a slug. Stable across versions of the mod.game.name— required in the first event orhelloper session; at most 64 characters.game.exe— optional, a file name only. It ties events to the detected game folder and lets that exe start the replay buffer.type— required. Either a standard type (the shared vocabulary inDocs/CLIPS.md: kill, death, assist, multikill, roundWon, roundLost, matchWon, matchLost, mvp, objective, lap, bestLap, position, crash, incident, levelUp, bossKill, zone, achievement, goal, save, mission, fightWon, penalty, pit, finish, raceWon, landing, takeoff) or"custom". The list inDocs/CLIPS.mdis authoritative and only grows. An unknown standard type is rejected with400.customType/customLabel— required whentypeis"custom".customTypematches[a-z0-9_.-]{1,32};customLabelis at most 40 characters and is the toggle name shown in the card.label— optional display text for this one event (marker tooltip, clip title), at most 80 characters.tags— optional, at most 8 tags, each matching[a-z0-9_-]{1,24}.context— optional map, level or area used in highlight titles, at most 64 characters.time— optional ISO-8601 UTC. Engine stamps the arrival time. Atimewithin ±5 s of arrival refines that stamp; anything else is ignored.- Unknown fields are ignored, so future versions only add fields.
- Character limits count UTF-16 code units, as JavaScript
lengthand .NETstring.Lengthdo. Patterns must match the whole value: a trailing newline is invalid. Strings that are empty or only whitespace count as missing. - Do not send personal data. Labels and contexts can appear in clip titles and file names.
4. hello (optional, recommended)
{ "v": 1, "game": { "id": "com.example.mygame", "name": "My Game", "exe": "MyGame.exe" },
"type": "hello",
"offers": ["kill", "death", "bossKill", { "customType": "parry", "customLabel": "Parry" }],
"log": "%LOCALAPPDATA%\\MyGame\\Saved\\Logs\\MyGame.log" }- Lets Hovermate create the game's card with its highlight toggles before the first real event arrives.
offerslists standard types and/or custom type objects.log(optional) proposes a log file for the log-line convention;files(optional) proposes mod-folder event files (§2.4). Hovermate asks the user before it starts reading any proposed path.hellois accepted over every transport, including a[HOVERMATE]log line.
5. Hovermate behaviour
- The first valid event or
hellofrom a newgame.idcreates an "SDK" game card. It uses the name, the exe (game folder/cover when the exe matches an installed game), a highlight toggle per offered or seen type, and before/after settings. It is off for highlights until the user turns types on; markers are always written. - Events go through the same pipeline as built-in cards: journal, markers in clips and sessions, the highlight window, notifications.
- The game is attributed to the detected foreground game when
game.exematches it. Otherwise events are accepted only while a recording or buffer is running, and are tagged with the SDK game. -
Limits:
- 20 events/s per game;
- 200 custom types per game;
- inbox lines over 4 KB are dropped;
- malformed lines are counted and shown in the card's status ("N invalid events"), never logged raw.