Khundian-Shadows_of_Doubt_Tracker_Control icon

Shadows of Doubt Tracker Control

A lightweight BepInEx plugin for Shadows of Doubt that lets you mute specific tracker “Movement Alert” toasts by location. Open the UI with F8 (default), hotkey can be changed in config. Requires BepInEx 6 IL2CPP.

CHANGELOG

Changelog

0.5.0

Initial public build focused on muting tracker toasts by location.

  • Added

    • Per‑location muting for tracker “Movement Alert” toasts.
    • In‑game Tracker Control UI (default hotkey: F8).
    • Optional suppression of related audio: nearby world one‑shots and 2D UI pings during a short window.
    • Automatic learning of location names from alerts; persistent list with filter, remove, mute/unmute all, reload, center.
  • Configuration (BepInEx Khundian.SoD.TrackerControl.cfg)

    • Mute.EnablePerTrackerMute (bool, default true): master toggle.
    • Mute.MuteTrackerNamePatterns (string): comma/semicolon list; case‑insensitive substring match; * accepted but treated as contains (e.g., City Hall*City Hall).
    • Mute.AudioMuteWindowMs (int, default 100): suppress nearby world SFX for this many ms after a mute.
    • Mute.MuteUIPings (bool, default true): also suppress 2D UI pings during the mute window.
    • UI.TrackerMuterToggleKey (string, default F8): UI toggle hotkey (KeyCode name).
    • Mute.KnownTrackerLocations (string): internal, learned locations (semicolon‑separated).
  • UX & Safety

    • UI opens only while in‑game; closes in menus.
    • Uses Desktop Mode while open; unlocks mouse cursor; pauses/resumes gameplay; disables/enables movement & mouselook; restores crosshair and typing focus on close.
    • Pressing Esc while the UI is open closes the UI and consumes the key to prevent the game menu from opening on the same press.
  • Technical Notes

    • Harmony patches:
      • InterfaceController.Update: strips muted messages from notificationQueue and starts the audio mute window.
      • InterfaceController.GameMessages() state machine: skips muted items by advancing the iterator.
      • GameMessageController.OnEnable/Update: kill‑switch/render‑guard destroys late‑identified muted toasts; reflection used to avoid TMP dependency.
      • AudioController.PlayWorldOneShot/Play2DSound: suppresses related audio during the mute window (radius ~25m for world SFX).
  • Compatibility

    • BepInEx 6 (Unity.IL2CPP). Windows paths shown; other OS layouts may differ with BepInEx.