Snitch
| Latest release | 1.6.1 |
| Download | GitHub · Thunderstore |
| Requires | MelonLoader 0.7.3, S1API Forked 3.1.1, Hotline 1.2.0 |
| API | Reference |
A performance profiler for Schedule I - measure what’s actually slow, then make it fast.
🛟 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 built on S1API - 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.
Features
Section titled “Features”- Frame time distribution + fps + GC pressure - the load-bearing, build-independent truth.
- Section costs - time named code sections (yours via the API, or vanilla hot paths like
NPCMovement.Update). - State distributions - NPCs by movement/visibility, trash by physics state, quests by state, and your own.
- Per-mod panels - any mod that reports data gets its own panel (counters, state, text, action buttons, toggles) in the Hotline overlay and the web dashboard.
- Log timeline - a combined, chronological view of every mod’s log output, with per-mod filtering.
- Ablation A/B - toggle a subsystem off and measure the real frame-time delta (the causal “total cost”).
- Live web dashboard - opens straight to your local game over WebSocket; your telemetry never leaves your PC.
- Phone remote - scan a QR (in the dashboard or the in-game Snitch panel) to drive the profiler from your phone: live FPS, Start/Stop/Reset, and every mod’s actions and toggles. Works on the same Wi-Fi or across networks, end-to-end encrypted.
- Honest - every number self-certifies; Snitch even reports its own overhead (
Snitch.Self). - Modder API - a zero-overhead no-op when Snitch isn’t installed, so you can ship it with no hard dependency.
Requirements
Section titled “Requirements”| Requirement | Version / Notes |
|---|---|
| Schedule I | IL2CPP build |
| MelonLoader | 0.7.x |
| S1API | ifBars-S1API_Forked |
| Hotline | The in-game overlay framework Snitch’s panel renders in (auto-installed as a dependency). |
Installation
Section titled “Installation”Mod manager (Thunderstore / r2modman): install Snitch; the dependencies (MelonLoader, S1API, Hotline) pull in automatically.
Manual: install MelonLoader 0.7.x, S1API and Hotline, then drop Snitch.dll into the game’s Mods/ folder.
Configuration
Section titled “Configuration”Settings live in UserData/MelonPreferences.cfg under Snitch_01_Main (or the in-game Mod Manager UI). The
profiler is idle until you run snitch start.
| Setting | Default | What it does |
|---|---|---|
Enabled | true | Master switch. OFF = Snitch does nothing. |
EnableInMultiplayer | true | Profiling runs locally on every peer; state-mutating levers stay host-only. |
AutoStart | false | Begin sampling automatically on world load. |
PollHz | 4 | How often state providers + counters are sampled (frame-time is every frame). |
ServerEnabled | true | Run the loopback data server for the web dashboard. |
ServerPort | 6140 | The loopback port (127.0.0.1 only). |
ServerToken | (empty) | Optional pairing token for the dashboard. |
AllowedOrigins | https://snitch.doodesch.de | Web origins allowed to connect from the browser (localhost is always allowed). |
The in-game overlay is provided by Hotline - press F6 to open it; Snitch’s panel (Start/Stop/Reset plus live stats) is inside, alongside every other mod’s.
Snitch’s own console:
snitch start/snitch stop- arm / disarm sampling (or the Start/Stop buttons on Snitch’s panel in the Hotline overlay).snitch panels- list the per-mod panels (toggle their windows from the Hotline overlay).snitch act <id>/snitch toggle <id>/snitch log [<channel>|all]- run a panel action, flip a toggle, or read the logs.snitch top/snitch sections/snitch states/snitch counters- log the current numbers.snitch vanilla on- attribute CPU cost to vanilla hot paths (e.g.NPCMovement.Update/FixedUpdate).snitch ablate <lever>- measure a subsystem’s causal frame cost (built-innpclever;snitch leverslists them).snitch report [md|csv|all]- export toMods/Snitch/runs/.
Or open the web dashboard at snitch.doodesch.de (or the copy bundled
offline at http://localhost:6140/) - it auto-connects and shows frame times, section costs, and state
distributions live.
For modders
Section titled “For modders”Your mod’s per-frame methods (OnUpdate etc.) are auto-timed with zero code - it just appears as
<YourMod>.OnUpdate once Snitch is sampling. To go further, drop in Snitch.cs (or reference
Snitch.Api.dll) - a zero-overhead no-op when Snitch isn’t installed - and either name a class SnitchProbe
with a static Register() (auto-discovered, no wiring). There you can build your own panel - counters,
state, free text, action buttons, toggles and a log channel, shown in the Hotline overlay and the web dashboard:
using Snitch.Api; // Profiler, Panel, StateSnapshotPanel p = Profiler.RegisterPanel("MyMod", "My Mod");p.Counter("QueueLength", () => _q.Count, "items"); // a numeric gaugep.State("Jobs", () => new StateSnapshot { Title = "Jobs" }.Add("running", _r)); // a distributionp.Action("Flush", () => Flush()); // a button (replaces a debug hotkey)p.Toggle("Verbose", () => _v, x => _v = x); // an on/off controlp.Log(); // show this panel's log channelusing (Profiler.Sample("MyMod.Pathfinding")) { ... } // hand-time a sub-sectionSee the SnitchExample mod for the full surface, and the Modder API wiki page.
How it works
Section titled “How it works”ProfilerRecorder engine counters are inert in Schedule I’s IL2CPP build, so Snitch relies on frame-time +
GC as the truth and self-measured section timing (Harmony accumulators) for attribution. The web
dashboard (snitch.doodesch.de, source at
ScheduleOne-SnitchWeb) is served both from that
hosted site and bundled inside the mod for offline use; either way the page connects straight to
ws://127.0.0.1:6140 so your data stays on your machine.
Compatibility
Section titled “Compatibility”Profiling is read-only and safe alongside other mods (it even observes their effects). State-mutating features
(the ablation levers) run host-only in multiplayer. The profiler stays idle until you run snitch start.
Credits
Section titled “Credits”Built by DooDesch on S1API by ifBars.
License
Section titled “License”MIT - see LICENSE.md.