You are viewing a potentially older version of this package. View all versions.
DooDesch-Snitch-1.6.1 icon

Snitch

A performance profiler - measure the cost + state of NPCs, trash, quests and your own mods, with a per-mod panel in the Hotline overlay, a live web dashboard, and a phone remote (scan a QR to drive it).

Date uploaded 5 days ago
Version 1.6.1
Download link DooDesch-Snitch-1.6.1.zip
Downloads 64
Dependency string DooDesch-Snitch-1.6.1

This mod requires the following mods to function

LavaGang-MelonLoader-0.7.3 icon
LavaGang-MelonLoader

The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono

Preferred version: 0.7.3
ifBars-S1API_Forked-3.1.1 icon
ifBars-S1API_Forked

S1API is an open source collaboration project to help standardize Schedule One modding processes. The goal is to provide a standard place for common functionalities so you can focus on making content versus reverse engineering the game.

Preferred version: 3.1.1
DooDesch-Hotline-1.2.0 icon
DooDesch-Hotline

One overlay and one key for every mod's HUD - and it auto-catches mods that grab function keys.

Preferred version: 1.2.0

README

Snitch

A performance profiler for Schedule I - find out what's actually slow.

🛟 Need help or found a bug? Get support at support.doodesch.de/snitch.

Snitch measures the cost and state of NPCs, trash, quests, and - through a tiny no-op API - any other mod's systems. Its in-game panel lives in the Hotline overlay (each mod gets its own panel), alongside a combined log timeline and a live web dashboard so you can see frame times, section costs, and entity-state distributions in real time, and make your mod (or vanilla gameplay) faster.

Version Game MelonLoader S1API

Live dashboard · Wiki / docs · Modder example · Support

Features

  • Frame time distribution + fps + GC pressure - the load-bearing, build-independent truth.
  • Section costs - time named code sections (yours, or vanilla hot paths like NPCMovement.Update).
  • State distributions - NPCs by movement/visibility, trash by physics state, quests by state, + your own.
  • Per-mod panels - each mod that reports data gets its own toggleable, movable, resizable panel (counters, state, text, buttons, toggles).
  • Log timeline - a combined, chronological view of every mod's log output, filterable per mod.
  • Ablation A/B - toggle a subsystem off and measure the real frame-time delta (causal "total cost").
  • Live web dashboard - opens straight to your local game over WebSocket; telemetry never leaves your PC.
  • Phone remote - scan a QR (dashboard or in-game panel) to drive the profiler from your phone: FPS, Start/Stop/Reset, and every mod's actions and toggles. Same Wi-Fi or across networks, end-to-end encrypted.
  • Honest - every number self-certifies; Snitch even reports its own overhead.
  • Modder API - a zero-overhead no-op when Snitch isn't installed; no hard dependency.

Requirements

Requirement Notes
MelonLoader 0.7.x (IL2CPP)
S1API ifBars-S1API_Forked
Hotline The in-game overlay framework Snitch's panel renders in (auto-installed as a dependency).

Use it

Install Hotline (pulled in as a dependency) and press F6 for its overlay; Snitch's panel is inside, with Start/Stop/Reset and live stats. Then snitch start (or the Start button on the panel). Or open the web dashboard at snitch.doodesch.de - it auto-connects and shows everything live. Console verbs: start, stop, status, frame, top, sections, states, counters, panels, act, toggle, log, vanilla on|off, ablate <lever>, levers, report. Reports go to Mods/Snitch/runs/.

For modders

Your mod's OnUpdate etc. are auto-timed with zero code (<YourMod>.OnUpdate). For more, drop in Snitch.cs (or reference Snitch.Api.dll) - a no-op when Snitch isn't installed:

using Snitch.Api;   // Profiler, Panel, StateSnapshot
Panel p = Profiler.RegisterPanel("MyMod", "My Mod");             // your own panel in the overlay + dashboard
p.Counter("Queue", () => _q.Count, "items");                     // a gauge
p.Action("Flush", () => Flush());                                // a button (replaces a debug hotkey)
p.Toggle("Verbose", () => _v, x => _v = x);                      // an on/off control
using (Profiler.Sample("MyMod.Work")) { ... }                    // hand-time a sub-section

Or just name a class SnitchProbe with a static Register() - Snitch discovers and calls it automatically. Full example: ScheduleOne-SnitchExample.

Notes

ProfilerRecorder engine counters are inert in Schedule I's IL2CPP build, so Snitch relies on frame-time + GC and self-measured section timing. Profiling is local and safe in multiplayer; state-mutating features run host-only. Everything is idle until you snitch start.

Credits

Built by DooDesch on S1API.

CHANGELOG

Changelog

All notable changes to Snitch are documented here. Format based on Keep a Changelog.

[1.6.2] - 2026-08-09

Fixed

  • A mod's debug build no longer hunts for Snitch on every API call when Snitch is absent. It searched five folders per call, hundreds of times during one world load.
  • Log lines no longer repeat the mod's own name. MelonLoader already puts it in front of every line.

[1.6.1] - 2026-08-04

Changed

  • snitch shows up in the game's command list, so a console autocomplete or a terminal can offer it and complete it. It was answered by a patch and registered nowhere, which made it invisible to every tool that lists commands. Nothing about running it changes.

[1.6.0] - 2026-08-04

Added

  • snitch open and snitch close show and hide the profiler panel without touching the keyboard. snitch open all and snitch close all do the same for the whole overlay. Needs Hotline 1.3.0 or newer.

[1.5.1] - 2026-08-01

Changed

  • Runs on Schedule I 0.4.6f11.
  • Needs S1API 3.1.1, up from 3.0.5. Update it along with the mod.

[1.5.0] - 2026-07-31

Tune a mod's values by dragging them, and open the dashboard without leaving the game.

Added

  • Sliders in mod panels. A mod can expose a value as a slider (Profiler.RegisterSlider, Panel.Slider) instead of a number you type into the console. Snitch clamps it to the declared range and snaps it to the step before the mod's setter runs, so every write path - dragging in game, the web dashboard, the phone remote, snitch slider - is bounded identically.
  • Sliders render everywhere panels already do: the in-game overlay, the web dashboard and the phone remote.
  • snitch slider <sliderId> [value] reads or writes one from the console. Omit the value to read it back. A slider is a mouse control and cannot be driven by a test harness; this is the scriptable equivalent.
  • Open dashboard button in the Snitch panel, and snitch dashboard. It serves the bundled copy from Mods/Snitch/wwwroot when one is present, otherwise the hosted build, which connects back to the same loopback socket. With the data server off it says so rather than opening a page that cannot connect.

Fixed

  • snitch hud and snitch panel <id> were still documented after 1.3.0 moved the overlay to Hotline, so following the docs printed "unknown". The wiki now matches the commands that exist.

Requirements

  • In-game sliders need Hotline 1.2.0 or newer, which draws them. Without Hotline, Snitch still runs and the sliders remain usable from the console and the dashboard.

Notes

  • Control ids are slugified from the label and punctuation is dropped, so two labels differing only in punctuation collide and the second replaces the first. Give each control distinct words.

[1.4.0] - 2026-07-08

Use your phone as a remote for the profiler - scan a QR and start/stop sampling or trigger any mod's actions without switching back to the browser window.

Added

  • Phone remote. A "Connect a phone" QR - both in the web dashboard and in the in-game Snitch panel. Scan it and you get a compact remote: the live FPS, Start/Stop/Reset, and every mod's panel actions and toggles.
  • Works on the same Wi-Fi (the phone connects directly to the game) and across networks (the game relays through a small pairing service, so it works even over mobile data). On the same network the phone switches to the direct local connection on its own.
  • End-to-end encrypted with a one-time key carried in the QR, so the relay only ever forwards ciphertext - your telemetry stays private even over the internet.
  • Turn it on from the Snitch panel toggle or with snitch lan on (off by default).
  • The dashboard now reads a capability list from the connected instance, so it only offers features the running build actually supports.

Requirements

  • The in-game QR uses Hotline 1.1.0 or newer (its panel image support). Everything else works without it.

[1.3.0] - 2026-06-26

The in-game overlay moves to the new Hotline framework, so every mod shares one overlay and one hotkey. The web dashboard and the profiling itself are unchanged.

Changed

  • The in-game overlay is now provided by Hotline (a dependency). Snitch contributes its profiler panel (frame stats, sections, states, Start/Stop/Reset) to the unified Hotline overlay, opened with Hotline's master key (default F6).

Removed

  • Snitch's own in-game windowing and its overlay settings (ShowHud, HudFontSize, HudX, HudY, WindowLayouts) and the snitch hud / snitch panel <id> console verbs - the overlay lives in Hotline now.

Note

  • Without Hotline, Snitch still profiles and serves the web dashboard, but has no in-game overlay. Hotline is pulled in automatically as a dependency.

[1.2.0] - 2026-06-25

The on-screen overlay becomes a small windowing layer, every mod gets its own panel, and there is a combined log timeline. The modder bridge ABI is unchanged (additive), so existing integrations keep working.

Added

  • Multi-window overlay: the profiler HUD is now an "Overview" window alongside per-mod panels and a log "Timeline". Each window is independently shown/hidden, dragged (title bar) and resized (bottom-right grip), with a scrollable body and a layout that persists across restarts.
  • Per-mod panels: any mod that reports data gets its own toggleable panel of counters, state distributions, free text, action buttons, toggles and a log channel - in the overlay and the web dashboard. New modder API: the Profiler.RegisterPanel(...) fluent builder (Counter/State/Text/Action/Toggle/Log) and Profiler.Log(...).
  • Log timeline: a combined, chronological view of all channels (each mod plus Snitch and the console), with per-mod filtering, both in-game and on the dashboard.
  • Arm sampling from the overlay: Start / Stop / Reset buttons in the Overview (no console needed). F6 toggles the overlay and always summons the Overview, so it can't get stuck closed.
  • New console commands: snitch panels, snitch panel <id> [on|off|move|size|reset], snitch act <id>, snitch toggle <id>, snitch log [<channel>|all].

Changed

  • The on-screen "resize" is now a real window resize (width/height with scrolling); font size is a separate setting. Button labels no longer clip descenders.

[1.1.0] - 2026-06-24

The on-screen HUD is now movable and resizable, and remembers where you put it.

Added

  • HUD position and font size are adjustable and persist across restarts: snitch hud move <x> <y>, snitch hud font <n>, and snitch hud reset (back to defaults), plus matching HudX, HudY, and HudFontSize settings (sliders in the Mod Manager UI). The overlay auto-fits, so a bigger font makes a bigger window.
  • Drag the HUD with the mouse: grab the body to move it, or its bottom-right corner to change the font size (works while the cursor is free, e.g. with the phone or pause menu open).

Fixed

  • The F6 hotkey now actually toggles the HUD (it was documented but never wired up).

[1.0.2] - 2026-06-22

Less code in mods, more profiling for free. No change to the host data/wire protocol or the bridge ABI, so existing integrations keep working.

Added

  • Auto-instrumentation: while sampling, every other loaded mod's per-frame methods (OnUpdate, OnFixedUpdate, OnLateUpdate, OnGUI) are timed automatically and shown as <Mod>.OnUpdate - per-mod frame cost with zero code on the mod's side. Toggle with the AutoInstrument preference.
  • Zero-wiring registration: a mod's SnitchProbe.Register() is now discovered and called by the host automatically when sampling starts, so a mod no longer wires a registration call into its OnInitializeMelon.

Changed

  • Modder API shim class renamed Snitch.Api.Snitch -> Snitch.Api.Profiler (drops the using Prof = ... alias; just using Snitch.Api; then Profiler.Sample(...)). The bridge contract is unchanged, so previously shipped shims still bind and report.
  • Cheaper no-op path: the shim's pre-bind host lookup no longer scans every loaded assembly each call.

[1.0.1] - 2026-06-22

Internal cleanup. No functional or behavioural changes.

Changed

  • Removed leftover development scaffolding: the dev-only verification probes and all internal "phase"-process references in code comments, console help, and docs.

[1.0.0] - 2026-06-22

Initial release. Feature-complete and verified in-game.

Added

  • Frame-time + GC sampler (the load-bearing measurement layer).
  • Stopwatch section timer (Snitch.Sample), backing both the modder API and vanilla probes.
  • Built-in state providers: NPCs (movement/visibility), trash (physics), quests (state).
  • Vanilla CPU cost attribution via Harmony accumulators (snitch vanilla on) - e.g. NPCMovement.Update/FixedUpdate.
  • Ablation A/B harness with a stability gate + lever registry (snitch ablate <lever>), built-in npc lever.
  • Local HTTP + WebSocket data server (loopback :6140) with CORS/PNA/Origin/token.
  • SnitchWeb live dashboard (React + uPlot), bundled offline at http://localhost:6140/.
  • Zero-overhead modder API (Snitch.Api) - copy-in source or referenced DLL, no hard dependency.
  • In-game HUD, periodic telemetry, and Markdown/CSV report export.