Sueta

skTrace

0.1.5

This project adds a profiler for Skript that shows which triggers and lines are eating your server's tick time, and turns the results into an interactive report you can share with one link.

·Script
  1. 0.1.5latestskTrace 0.1.5Sep 1, 2026

    [0.1.5] - 2026-08-05

    - Added /sktrace loops, a live view of the loop and while sections running right now: what each one is, where it lives (script:line), the iteration it's on, how fast that number is climbing, how long it has been going, and how many copies of it are running at once. It's built for the loop that "just keeps going" - the one you'd otherwise hunt down by scattering broadcasts through your code. A counter that keeps climbing and never clears is your runaway, and the row turns amber, then red, as it starts to look like one. - Added a Loops panel to HTML reports, listing every loop seen running during the capture with its peak iteration count, peak concurrency, and whether it was still going when the report was written. The panel stays hidden when no loops were observed. - Added frozen-server detection for the case the loops view cannot cover. A loop with no wait inside never yields, so an infinite one pins the server's main thread and nothing in-game - not even /sktrace loops - can run. skTrace now watches for that from its own background thread and, once the server has stopped ticking for loop-hang-seconds (10 by default), logs the responsible loop's script:line to the console, the one surface still alive during a freeze. It is detection only: it never stops, kills, or interrupts anything. Turn it off with loop-hang-detection: false. - Loop watching is on by default and safe to leave on: unlike line-level-profiling, it only reads the iteration counter Skript already keeps for every loop and never rewrites how a script runs. Loops are found once, when profiling starts, and sampled about once a second on skTrace's existing tick task, so there's no new scheduler task and no per-iteration cost. Only loops that span ticks (that is, contain a wait) can be observed - a no-delay loop finishes inside a single tick, leaving nothing to see. Disable the whole feature, including the startup scan that finds loops, with loop-watching: false. - Fixed skTrace claiming per-trigger timing was unavailable on your Skript version when it was working fine. If a capture ever started at a moment when no event triggers were loaded (every script is commands or every N seconds, or scripts had not finished loading yet), the warning latched on and stayed on for the rest of the server's life: every later /sktrace start repeated it, and every report was stamped with it, including reports whose Triggers table was fully populated. An empty registry is now recognised for what it is, "nothing to hook yet", and the check is re-run on each capture instead of being decided once. - Fixed every Skript command collapsing into a single report row called simple event "simple event". Skript builds a command's trigger on a generic event whose own label is that placeholder text, so all of them shared one name, and sharing a name meant sharing one set of timings: three commands showed up as one row, at the line number of whichever unrelated trigger happened to be registered first. Each command is now its own row, named after the command (command /home), and other triggers that use the same generic event fall back to the event line you actually wrote. - Fixed /sktrace reset quietly ending per-trigger and per-function collection for the rest of the capture. Only event-level timings kept recording afterwards, so the Triggers and Functions tables stayed empty until the next script reload or profiler restart, with nothing to indicate why. Collection now resumes immediately. - Fixed /sktrace reset not clearing function times, so after a reset the Functions table showed lifetime totals next to a freshly reset window. - Changed the console output of /sktrace start. The hook-install detail (registry scan, per-field dump, hooked counts) is now off by default, since it repeats on every capture and every /sk reload and says nothing an operator can act on. Set debug-logging: true in config.yml to bring it back, or run /sktrace diag, which dumps the same Skript internals on demand. Genuine problems are still logged as warnings either way. All Verified against Minecraft 26.2 on Skript 2.16.1
    131 downloads
  2. 0.1.4skTrace 0.1.4Jun 11, 2026

    [0.1.4] - 2026-06-10

    - Added an out-of-date warning on shared reports. Each report now records the skTrace version that produced it, and the website checks that version against the latest release on Modrinth - when a report came from an older build, it shows a banner at the top prompting an update, with a link to the current version. Reports made before this change carry no version, so the site falls back to recognizing an older build from the report's own data, and those are flagged too. A report from a current build (or a dev build ahead of the release) is never flagged. - Fixed (properly this time) Skript events firing twice after a script reload while skTrace was profiling. 0.1.3 detected reloads by watching for the /sk reload command, which missed every reload that wasn't typed by a player or the console - a script running execute console command "sk reload ...", a panel plugin or addon reloading scripts programmatically, and similar. skTrace now registers with Skript's own script load/unload events (modern Skript), so Skript's real triggers are restored before any unload - no matter how the reload was started - and re-hooked once loading settles. On Skript versions without those events, the 0.1.3 command detection remains as a fallback. Thanks Jake! - Fixed the failure mode that made the doubling permanent - surviving profiler stops and even plugin updates, and fixable only by a full server restart. When a reload slipped past 0.1.3's detection and the profiler later stopped (or skTrace was updated via a plugin manager, which stops it on unload), skTrace wrote its backed-up trigger entries back into Skript's registries by list position. The registries had changed since the reload, so originals from the unloaded script generation could land back inside - or on top of - the new generation's entries, as orphans Skript can never remove. Every restore is now identity-checked: an original goes back only into the exact spot that still holds its skTrace wrapper, and anywhere Skript has rebuilt is left untouched. - Fixed the same trigger being wrapped twice when it was reachable through two of Skript's registries (the event map and the script structures). Both now share a single wrapper - which also means that even if a reload were somehow missed entirely, Skript's own unload cleanup now finds and removes skTrace's wrapper by itself, so duplicate firing can't take hold in the first place.
    273 downloads
  3. 0.1.3skTrace 0.1.3Jun 8, 2026

    [0.1.3] - 2026-06-08

    - Added a variable viewer in reports: how many global variables were created, updated, and deleted during the window, the most-written ones, and a writes-per-tick sparkline. It passively observes Skript's variable save path — the same path that writes variables.csv (or your database) — without touching how scripts run, and it never reads or scans your existing variables, so there is no cost from a large variables.csv. Global variables only (local {_temp} variables are never persisted, so cannot be tracked). On by default; opt out with variable-tracking: false. - Added the ability to open a report on the website by uploading its file. The .json report file is now a complete, self-contained report, so when an auto-upload is skipped or fails (for example HTTP 413, "report too large"), /sktrace report points you to the homepage where you can drop the .json in and get a shareable link. On busy servers the variable list is collapsed behind a "Show variables" dropdown so it never overwhelms the page. - Added a running count of reports shared, displayed on the website. - Added automatic config migration: updating skTrace now merges any new config.yml options into your existing file (keeping every setting you've changed), instead of leaving a stale config behind on update. skTrace also warns at startup if the experimental line-level-profiling is enabled, since it can disturb how some scripts run while profiling. - Added disk-save tracking: skTrace now detects Skript's periodic full rewrite of variables.csv (the save that runs about every 5 minutes) when it happens during a capture, and draws it as a band on the tick chart alongside roughly how long it took and the file size. While that rewrite runs it holds Skript's variable lock, so scripts setting variables stall until it finishes — this lets you see at a glance whether a save lines up with a lag spike. It watches the file on disk (never reads its contents) and only applies to flat-file storage; part of variable-tracking. Add --variable-values to /sktrace report (or clip) to also list, under each save, the exact variables it compacted with their latest values — masked like option secrets unless --show-secrets is also set. - Added an update notifier: skTrace checks Modrinth on startup (and every few hours after) for a newer release and, when one is out, tells operators — anyone who is op or has sktrace.use — with a clickable download link when they join, and logs it once to the console. It is a notification only and never downloads or installs anything; the check runs off the main thread. Turn it off with update-checker: false. - Fixed rolling-mode counts climbing for the whole session instead of the buffer window: the Calls and Total time on the Triggers, Functions, and Events tables (and the donut / "time by script" that derive from them), plus the Variables section's Total writes / Created / Updated / Deleted, now reflect only the retained rolling window. A long-running buffer previously showed counts in the millions. One-shot start/stop reports are unchanged (their window is the whole run), and the selected-range breakdown was already window-scoped. Max single-call time stays all-time (there are no per-call samples to window it by); the per-variable list and distinct-name count are still cumulative for now. - Fixed stale scripts lingering in reports: a report now leaves out triggers and functions whose script Skript no longer has loaded (deleted, disabled, or unloaded since they were hooked), checked fresh each time a report or clip is written. Previously a removed script could keep appearing — most visibly with the rolling buffer, which accumulates across clips without clearing. Fails safe: if the loaded-script set can't be read, nothing is hidden. - Fixed Skript events firing (and triggers running) twice after /sk reload while skTrace was profiling — on join running twice, on right click twice, and so on, until a full server restart. skTrace's per-trigger profiling replaces Skript's internal trigger objects with timing wrappers; because Skript unloads scripts by matching triggers on exact identity, it could no longer find its own triggers and never unregistered the shared event listener, so the reload left a stale listener behind and registered a second one. skTrace now restores Skript's originals the instant it sees a reload command — before the unload — so Skript's cleanup succeeds, then re-applies its hooks against the freshly loaded scripts. Even if that re-apply is mistimed on a very large reload, events can no longer double; the worst case is briefly reduced profiling coverage until the next reload. - Fixed placeholder and addon events all showing as "simple event" in reports (and merging into a single row). Skript represents many addon events — skript-placeholders, SkBee custom events, and similar — with a generic event that has no label of its own, so every one of them showed the same name. They now display the actual event line you wrote (for example on "%player_balance%"), so each is labeled distinctly. Ordinary events such as on join are unchanged. - Report UI: the Triggers, Functions, Events, and trigger-breakdown (selected-range) tables now show the top 5 rows with a "Show N more" dropdown for the rest (the kept rows follow whatever column you sort by), matching the Variables list. The breakdown's old fixed 40-row cutoff is replaced by this dropdown, so every trigger in a range is reachable. - Report UI: the tick chart's Y-axis switches to seconds for large values (e.g. 2.6s instead of 2556ms) so big spikes no longer clip the axis labels; "Show more" / "Show variables" toggles no longer render as an empty button when there's nothing to expand.
    30 downloads
  4. 0.1.2skTrace 0.1.2Jun 4, 2026

    [0.1.2] - 2026-06-04

    - Added function-level profiling: per-function timing in reports, with per-line detail inside functions available as an opt-in. - Report UI: mobile rendering fixes (legible tick chart, touch range-select, horizontally scrollable tables, ellipsized long names with tooltips), clearer labels, and worst-tick severity colors (green / amber / red). - In-game UI: refreshed all chat messages and the boss bar, a branded header rule on /sktrace help and status, tightened copy so nothing wraps, report flags moved into a hover, and an on-brand boss bar.
    40 downloads
  5. 0.1.1skTrace 0.1.1Jun 1, 2026

    [0.1.1] - 2026-06-01

    - Fixed a potential crash (ClassCastException + console spam) when profiling triggers with if all: / if any: / then:, and a related bug where else could run even after the if matched. - Fixed the shared report source viewer: long lines no longer break the highlights, timing column, or top bar when scrolling sideways. - Changed: line-level profiling is now opt-in (off by default) so a profile never disturbs a live server. Enable it with line-level-profiling: true in config.yml. Per-event and per-trigger timing are unaffected. - Faster: about half the per-statement overhead when line-level profiling is on. - Added a [bStats](https://bstats.org/plugin/bukkit/skTrace/31715) chart tracking how many servers enable line-level profiling.
    59 downloads
  6. 0.1.0skTrace 0.1.0May 27, 2026
    35 downloads

Similar projects

Script →