

ULTRAKILL doesn't track run stats, this fix.
ULTRASTATS is an all-in-one stat tracking, performance analysis, and data collection mod for ULTRAKILL.
Whether you speedrun, high round Cybergrind, play custom levels, or just want a better record of how you play, ULTRASTATS saves your run data and allows you to browse it in-game.
ULTRASTATS currently supports:
This plugin is currently on v0.1.2.
v0.1.0 is the first SQLite based release of ULTRASTATS. Older versions stored runs in many .jsonl files spread across difficulty, mode, campaign, and custom-level folders. New versions store runs in one database file:
ultrastats.db
Old .jsonl data can be migrated automatically. See Updating From Older Versions before deleting any old ULTRASTATS files.
These are from v0.0.15, the layout may be slightly different now.
Cybergrind stats:

Campaign stats:

Custom level stats:

The exact columns shown depend on the selected mode and filters. ULTRASTATS converts stored values into readable dates, times, waves, ranks, flags, level names, and difficulty names whenever possible.
ultrastats.db.jsonl data into SQLite.jsonl files after migration instead of deleting them automaticallyRequired:
Optional:
If you already have a working ULTRAKILL mod setup, install ULTRASTATS like any other BepInEx plugin.
Install BepInEx for ULTRAKILL.
Install PluginConfigurator.
Drop the ULTRASTATS plugin files into:
ULTRAKILL\BepInEx\plugins\
Launch ULTRAKILL.
Confirm the mod loaded by checking the BepInEx console or log.
To enable custom level logging, also install:
v0.1.0 changes the storage backend from .jsonl files to SQLite.
Older ULTRASTATS versions saved runs in a folder structure with separate files for different difficulties, modes, campaign levels, and custom levels. v0.1.0 stores new runs in one database file named:
ultrastats.db
This makes filtering and sorting much faster and makes future analysis features easier to build.
When ULTRASTATS starts:
ultrastats.db already exists, ULTRASTATS uses it.ultrastats.db exists but the old .jsonl file structure exists, ULTRASTATS will create a new database and import the old runs..jsonl files are not deleted automatically.Do not delete your old ULTRASTATS folders until you have launched the game, opened the STATS tab, and confirmed that your old runs appear correctly.
ultrastats.db existIf ULTRASTATS detects both the new database and the old file structure, it may show a startup notice explaining the storage change. This notice can be disabled in PluginConfigurator.
ULTRASTATS adds a main menu button that opens its UI.
The UI contains:
The STATS tab can:
By default, ULTRASTATS stores data in:
%AppData%\AtomSmasher1586\ULTRASTATS
You can change the parent folder through PluginConfigurator. ULTRASTATS will still create and use its own ULTRASTATS folder inside the selected location.
The most important file in the data folder is:
ultrastats.db
This is the SQLite database that contains your saved run data.
Because v0.1.0 moved from .jsonl files to SQLite, new ULTRASTATS data can no longer be comfortably viewed or edited in a normal text editor.
To inspect or edit the database manually, use a SQLite database viewer such as:
Be careful when editing the database directly. It is very easy to delete or change data you did not mean to change. Make a backup of ultrastats.db before manual edits.
The database is intentionally small and practical:
runs stores the actual saved run records.levels stores campaign, Cybergrind, and custom level metadata.bundles stores custom level bundle metadata when available.Flags are stored as bit flags inside an integer. This is more compact and flexible than adding a new database column for every possible flag.
Ranks are also stored in an encoded integer format. Instead of saving rank letters as strings, ULTRASTATS stores compact numeric rank values that can be decoded into time rank, kills rank, style rank, and total rank.
Custom level logging is designed around Angry Level Loader.
When Angry Level Loader data is available, ULTRASTATS tries to resolve readable custom bundle and level names for the STATS tab. When that metadata is missing, ULTRASTATS falls back to stable IDs or file derived names where possible.
Custom level support is optional. Missing Angry Level Loader metadata should not prevent Campaign or Cybergrind logging from working.
ULTRASTATS is designed to be friendly to other mods where possible:
Because ULTRAKILL modding changes often, make sure ULTRASTATS, BepInEx, PluginConfigurator, and optional dependencies are up to date.
ULTRASTATS is still in active development.
The long term direction includes better analysis and visualization tools, especially in the PLOTS tab. That tab is intended to eventually hold things like:
If you use ULTRASTATS, feedback helps a lot.
Please reach out if you:
Discord: atomsmasher_1586
ULTRASTATS is meant to be a practical stats backbone for ULTRAKILL:
If you care about understanding your gameplay, improving at ULTRAKILL, or just want to see what your Cybergrind score was last week, this mod is for you.
For catching bugs and pointing out flaws in ULTRASTATS that I missed:
For allowing me to use his icons: