Skip to content

yeet-src/knicks-pbp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

knicks-pbp

htop, but it's a Knicks game — called live. Your CPU narrated from the Garden floor: a running score, a game clock, momentum, a crowd that roars, and a play-by-play feed off your busiest processes.

Linux yeet Discord

knicks-pbp demo

knicks-pbp is a live terminal system monitor skinned as a play-by-play broadcast from Madison Square Garden: the Knicks run on user CPU, THE DAEMONS counter with system + iowait, the lineup is your busiest processes, and a derived commentary feed calls the game as your machine plays it.

Tip

No kernel modules, no BPF, and no network. knicks-pbp reads /proc straight through yeet's graph API, so the same one-liner runs on any Linux box. The numbers are pure system telemetry — there is no live NBA data here, and nothing to fetch.

Quick start

curl -fsSL https://yeet.cx | sh
yeet run github:yeet-src/knicks-pbp

Manual install guide · Linux only

Play shorter quarters, or grab a single pipe-safe snapshot:

yeet run github:yeet-src/knicks-pbp -- --quarter-secs 30
yeet run github:yeet-src/knicks-pbp -- --once | cat

Flags

Live game (main.js)

  • --quarter-secs <n> (default 120) — wall seconds per quarter; four of them count down 12:00 → 0:00 and then it's FINAL.
  • --pace <n> (default 1100) — offense-percent-seconds per possession; lower scores more.
  • --interval <ms> (default 1000, floored at 100) — live refresh period.
  • --secs <n> — exit after n seconds (default: run until Ctrl-C).
  • --once — render a single snapshot and exit (automatic when output is piped).

JSON stream (dump.js)

yeet run github:yeet-src/knicks-pbp/dump.js -- --interval 1000
  • --interval <ms> — stream one game-state object every interval until FINAL (default: emit one snapshot, then exit).
  • --quarter-secs <n>, --pace <n> — same as above.

A 60-second primer on the broadcast

Every number on screen is real system telemetry wearing a basketball stat line.

The score is CPU, split by who's spending it. The kernel charges every tick of CPU time to either user mode (your programs) or system mode (the kernel working for them), plus iowait (a core parked on disk). The KNICKS offense is the user share; THE DAEMONS are system + iowait. Both are summed across every core as percent-of-one-core, so a single pegged core reads 100 and a busy 16-core box can push past a thousand. Offense doesn't post the score directly — it advances possessions: sustained pressure fills a shot clock, and crossing it drops a bucket (worth 2, or 3 from downtown), capped at one per refresh so a CPU spike can't run up a cartoon score.

CPU is a rate, not a reading. A process's /proc entry counts cumulative ticks since it started, so a single sample tells you nothing about right now. knicks-pbp takes two snapshots and scores the work done between them — which is why the game settles in over the first second and why --once pauses briefly to take its two samples.

The lineup is processes. The five busiest processes are on the floor. Each line: PLAYER is the process name, PTS is the points it has put up (the buckets attributed to it as the hot hand), REB is resident memory in MB, AST is its thread count, and CPU% is its share this refresh. A marks the current Player of the Game — the process with the most points.

Momentum and the crowd. Momentum is an orange↔blue tug-of-war eased toward whichever offense is hotter (smoothed, so one bucket can't swing it); a sustained Knicks edge becomes a run. MSG DECIBELS is a crowd meter blending load average, network throughput, and how lopsided the momentum is.

The play-by-play. The feed is derived from the telemetry, not scripted: a brand-new hot process checks in, a busy one that exits fouls out, a process running away with the CPU draws its own call, an 8-0 swing is a RUN, a memory wall is a timeout, a network burst is a fast break. Each line type is on a cooldown and the feed is capped, so it reads like a broadcast and not a log tail. Newest line sits at the bottom.

The game clock is wall time. Four quarters of --quarter-secs each, shown as a 12:00 → 0:00 countdown, rolling Q1 → Q4 → FINAL. It is monotonic and never runs negative.

Common use cases

Mostly the moments when you'd reach for top, except you wanted it to be fun.

  • Box feels busy. Who's actually eating the CPU right now — and is it user work or kernel/IO?
  • Something is thrashing the disk. Are THE DAEMONS (system + iowait) putting up points?
  • Quick glance at the busiest processes with memory and thread counts, narrated, without parsing top.
  • A live, glanceable monitor for a spare terminal or a wall display that isn't another grafana tab.

What you're looking at

Banner: a plain-text NEW YORK KNICKS vs THE DAEMONS / MADISON SQUARE GARDEN marquee in Knicks orange and blue. Text only — no logos.

Scoreboard: the two team totals drawn big in a seven-segment digit font, KNICKS on the left in orange, THE DAEMONS on the right in blue, the leader flagged with . The quarter and game clock sit beneath. On a narrow terminal the big digits collapse to a single KNICKS N vs N DAEMONS line.

MOMENTUM / DECIBELS: two meters — a center-pivot tug-of-war for momentum and a fill bar for the crowd.

ON THE FLOOR: the five busiest processes. Columns: PLAYER (name, truncated with an ellipsis), PTS (points scored), REB (resident MB), AST (threads), CPU% (share this refresh). flags the Player of the Game.

PLAY-BY-PLAY: the derived commentary feed, newest at the bottom, the latest few lines bright and older ones dimmed.

Footer: the load average as "tempo", the core count, the current KNICKS / DAEMONS offense, and the Player of the Game.

How it works

JS side (the whole thing). knicks-pbp is pure JavaScript with no compiled components.

  • main.js (entrypoint): terminal management, the render loop, and screen layout. Detects whether stdout is a PTY; if not, it falls back to a single snapshot automatically. Draws the seven-segment score, the meters, the box score, and the feed, clipping colored lines to the visible width without breaking ANSI escapes. Flags: --quarter-secs, --pace, --interval, --secs, --once.
  • data.js: one yeet.graph.query() call per sample, covering procs.stat (user/system ticks, RSS, threads, start time), kernel_stats (iowait), cpu, load_average, network_interface_stats, and host.uptime. Diffs two samples into a normalized game snapshot, matching a process across samples by PID and start time so a recycled PID can't inherit a predecessor's counters. It also holds the game engine — the persistent score, clock, momentum, crowd, and play-by-play state, advanced one tick at a time. Shared by both main.js and dump.js.
  • dump.js: alternate entrypoint. Emits the same game state as newline-delimited JSON, one object per refresh: score, clock, momentum, crowd, lineup, latest play-by-play, and Player of the Game. Pipe to jq. Accepts --interval to stream until FINAL.
  • demo.sh: spins up CPU busy loops to put points on the KNICKS side and a sync/IO loop to score for THE DAEMONS, then launches the game with short quarters. Override the home burn with LOAD=N.

Data flow. Each refresh: data.js queries yeet's graph layer (which reads /proc and /sys), diffs the previous sample into a snapshot, and feeds it to the game engine, which accumulates the score and derives the play-by-play. main.js renders the result in one synced write per frame, using the alternate screen buffer and cursor positioning to avoid flicker.

Requirements

Important

yeet itself is the only hard requirement. Everything here comes from /proc and /sys, present on all mainstream Linux distributions by default; no special kernel config, no elevated privileges beyond what yeet already uses to read the process table.

  • The yeet daemon, which handles process sandboxing and the graph API. curl -fsSL https://yeet.cx | sh installs it.

Honest caveats

Note

What knicks-pbp doesn't do, and where the metaphor bends.

  • There is no live NBA data, and there can't be. The yeet runtime has no network or HTTP access. Every number is local system telemetry; the basketball framing is presentation only. This is not affiliated with, endorsed by, or connected to the NBA or the New York Knicks.
  • The game needs two samples to start scoring. The very first frame, and a genuinely idle box, honestly read 00; on a quiet machine a low-scoring defensive battle is the correct game.
  • The score is tuned, not literal. Offense advances possessions through a shot-clock model so the final lands in a believable range; --pace shifts it. THE DAEMONS only score when the kernel is genuinely busy (system + iowait), so a healthy box often sees a Knicks blowout.
  • The lineup shows the top five processes by CPU this refresh. Short-lived processes that start and exit between two samples never appear.
  • The game clock is wall-clock folded into quarters, not a real game or a timer you should trust for anything.
  • Process names come from the command line (or the kernel's comm), truncated for the box score.

Community questions

1. Why is the score 0–0 when I start it? CPU usage is a rate. knicks-pbp needs two snapshots a moment apart to score the work done between them, so the first frame reads 00 and fills in on the next refresh. On a genuinely idle box, a low score is the correct game.

2. Why do the Knicks blow out THE DAEMONS? The Knicks are user CPU — your programs — and THE DAEMONS are system + iowait, which a healthy machine spends little time in. A lopsided home win usually means your box is doing real work, not fighting the kernel. The Daemons get cooking when something thrashes the disk or hammers the network stack.

3. Can I make it score more (or less)? Yes — --pace is offense-percent-seconds per possession. Lower it for a shootout, raise it for a grind. --quarter-secs sets how long the game runs.

4. Will this affect my system's performance? One /proc round-trip per second at default settings; the read load is negligible. demo.sh does spin up CPU and IO workers intentionally to put points on the board — that's opt-in and stops when you Ctrl-C.

5. How is this different from top or htop? Under the skin it's the same data — busiest processes, CPU split by user/system, load average, uptime. knicks-pbp reframes it as a live game with a running score, momentum, a crowd, and a derived play-by-play feed, and ships a pipe-friendly JSON stream via dump.js, all in a single yeet run with no installation. It's top you can leave on a wall display and actually enjoy.

License

knicks-pbp is pure JavaScript and currently ships without a dedicated license file in this repository.


Built with yeet, a JS runtime for writing eBPF programs on Linux machines. Join us on discord.

About

Your CPU called play-by-play from the Garden — a live system monitor skinned as a Knicks game (system-load-as-basketball). Fan-made; not live NBA data.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors