Project Deep Dive

Agent Support

Agent Support extends the GestureKit engine with production-grade features: a Global Cooldown manager that emulates SWTOR's 1.275s GCD timing, a Discord bot for remote control and notifications, a hardware-calibration system for latency tuning, and Omega profile support for high-complexity rotation sequences.

Node.jsTypeScriptDiscord.jsSupabaseRobotJS

Project Overview

Omega Profiles & GCD Manager

Calibration System Deep Dive

Context

Agent Support is the production layer I built on top of GestureKit to run my actual SWTOR characters. Where GestureKit is the general-purpose gesture detection engine, Agent Support is the application — 7 fully tuned character profiles, a Global Cooldown manager that understands the game's timing model, special-key behaviors that go well beyond standard macro execution, and a calibration system with a live WebSocket server for hot-reloading thresholds without restarting the engine.

The Omega Gesture System

Agent Support runs the Omega detector exclusively. Omega was designed around SWTOR's combat pace: long gestures fire the moment the hold threshold is crossed rather than waiting for key release, which eliminates the quarter-second lag that made the Alpha system feel sluggish during active rotations.

The four base gesture types are quick, long, quick_toggle, and long_toggle. The toggle variants require W or Y to be held past threshold before the gesture fires, creating a second layer of bindings on every key without adding any physical keys to the mapping. Three modifier layers extend this further:

  • F2 layer — F2 is an independent toggle that adds quick_f2 and long_f2 variants to every key in the system. Long-holding F2 also triggers the R-stream directly.
  • Q layer — Q modifier adds quick_q_toggle and long_q_toggle. Used for targeting sequences and target-of-target combos.
  • S layer — S modifier adds quick_s_toggle and long_s_toggle. In most profiles this layer is where group-member-targeting sequences live.
  • The result is up to 13 distinct gesture types per key across all layers, all resolved with zero ambiguity because each modifier state is tracked independently.

    7 Character Profiles

    Profiles are defined as TypeScript arrays of binding objects — `SHARED_BINDINGS` inherited by all characters plus per-character overrides — and compiled into O(1) lookup maps at startup. The seven profiles:

  • T — Tank (Vengeance Juggernaut) — D key runs continuous R-stream (steady threat generation), S key fires Guard as a dual-key press (targeting teammate + applying guard simultaneously)
  • R — Rage (Rage Juggernaut) — D key runs burst_stream_slow (paced burst with longer gaps), S key fires Smash with positional awareness
  • S — Sorc Heals (Corruption Sorcerer) — D key is single_press (no stream, burst healing doesn't benefit from it), S key fires Innervate
  • M — Madness (Madness Sorcerer) — D key runs burst_stream_fast (tight burst cycles), S key fires Crushing Darkness
  • E — Engi Sniper (Engineering Sniper) — D key is single_press, S key fires Shield Probe as a dual-key sequence
  • C — Combat Medic (Combat Medic Commando) — D key runs burst_stream_slow, S key fires Advanced Medical Probe
  • A — Arsenal Merc (Arsenal Mercenary) — D key runs burst_stream_fast, S key fires Heatseeker Missiles with spread-shot targeting
  • Every profile also configures per-key bindings for the number row (1–6), A, B, H, I, U, and all Omega modifier variants of those keys.

    D Key — Four Stream Modes

    The D key is not a standard gesture key. It toggles an R-stream: periodic synthetic R keypresses at configurable intervals, used to maintain continuous ability queueing in SWTOR. Four modes are defined per profile:

  • continuous_stream — R fires at a fixed interval indefinitely until toggled off (Tank profile)
  • burst_stream_slow — fires a burst of R presses with longer inter-burst gaps (Rage, Combat Medic)
  • burst_stream_fast — fires a burst with tight gaps for rapid ability chaining (Madness, Arsenal)
  • single_press — D fires one R press and stops, no looping (Sorc Heals, Engi Sniper)
  • Toggling D on announces the mode via TTS. Toggling it off silences it. The stream runs independently of gesture detection so active key presses don't interrupt the loop.

    S Key — Dual-Purpose Ability and Group Targeting

    S has two distinct behaviors separated by hold duration:

  • Quick tap — fires the profile-specific ability (Guard, Innervate, Shield Probe, etc.), often as a dual-key press that targets a specific party slot simultaneously
  • Long hold (512ms threshold) — activates Group Member Targeting mode. Once active, the number keys 1–4 and T are intercepted: pressing them assigns that slot to the designated DPS target position rather than triggering their normal gestures. This allows mid-fight retargeting without touching the UI or breaking the rotation. The mode deactivates automatically when S is released.
  • C Key — Double-Tap ESCAPE

    C implements hybrid quick/long detection with a double-tap intercept. A single quick tap fires the profile's C binding normally. A double tap within a 300ms window produces a synthetic ESCAPE keypress — useful for dismissing targeting cursors or closing dialogs mid-rotation without breaking hand position.

    GCD Manager

    SWTOR's global cooldown is exactly 1.275 seconds. The GCD manager tracks this timer in software and enforces a most-recent-wins queue:

  • When a GCD ability is requested while the GCD is active, the request is held in queue
  • When the GCD expires, the most recently queued ability fires immediately
  • Per-ability cooldowns are tracked separately from the GCD — an ability can be on its own cooldown even when the GCD is open
  • The manager integrates with the gesture executor so that long-hold gestures that fire before key release still respect the GCD state correctly
  • The practical effect: you can mash a key ahead of the GCD and the system fires the ability at exactly the right tick without double-pressing or missing the window.

    Calibration System with WebSocket Hot-Reload

    Timing calibration is per-machine. The calibration manager runs a measurement sequence, collects hold-duration samples across the monitored key set, and applies statistical analysis (mean, standard deviation, confidence scoring) to compute per-key thresholds. Results are stored as named calibration profiles.

    The calibration server runs a WebSocket server on port 8765. When a new calibration run completes, it broadcasts updated thresholds to any connected listeners — including the live gesture engine. This means you can recalibrate mid-session and have the new thresholds take effect immediately without restarting the process.

    Traffic Controller and Profile Compiler

    Several keys in SWTOR require modifier combinations (e.g., SHIFT+4) that coexist with unmodified versions of those same keys in other concurrent sequences. The traffic controller prevents contamination:

    At load time, the profile compiler performs a pass over all bindings and identifies conundrum keys — keys that appear both with and without a specific modifier in the active profile. These are stored in a lookup set. At execution time, the traffic controller checks whether a conflicting modifier (Shift, Alt) is physically held before emitting the keypress. If the modifier is held and the key is a conundrum key, the output is delayed until the modifier is released. This check has zero overhead for non-conundrum keys.

    Architecture

  • Omega Gesture Detector — per-key state machines, modifier layer tracking, instant-quick optimization for keys with no long binding
  • GCD Manager — 1.275s GCD timer, most-recent-wins queue, per-ability cooldown map
  • Profile Compiler — TypeScript binding arrays → O(1) lookup maps, conundrum key extraction
  • Traffic Controller — modifier-aware conflict resolution at output time
  • Sequence Executor — concurrent execution with RepeatPolice deduplication, Teensy serial routing, per-step timing
  • Calibration Manager — statistical threshold derivation, confidence scoring
  • Calibration Server — WebSocket on port 8765 for hot-reload of calibration results
  • Teensy 4.0 — USB HID via serial, `KEY:keyname:duration` protocol, auto-reconnect on disconnect