Agent skill

Procedural Lofi

by IvanWng97 in IvanWng97/pixtuoid

Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships.

MITAuto-check passedMedia & Creative

Install Procedural Lofi

skills CLI
$ npx skills add IvanWng97/pixtuoid --skill procedural-lofi -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install IvanWng97/pixtuoid procedural-lofi --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/IvanWng97/pixtuoid.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/procedural-lofi .claude/skills/procedural-lofi && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
procedural-lofi
GitHub stars
490
Token cost
~3.5k tokens
SKILL.md length
1,921 words
Files
8 (incl. scripts)
Skills in repo
5
Repo updated
First seen
Licence
MIT

At a glance

Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships.

  • Works in 5 steps: Audition in a scripting language first… → Reference-fingerprint each sound → Shape synthesis to the measured curve → …
  • Adding ambient/generative audio to an app
  • SKILL.md covers The core idea (why code, not…, The pipeline (five phases), The failure catalog (bugs this… and Quickstart for a fresh project, plus 1 more section
  • Runs Python scripts from its folder; calls yt-dlp, ffmpeg and python3

What it does

Procedural Lofi is an agent skill from IvanWng97/pixtuoid. Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships. Fingerprint a beloved reference recording, shape synthesis to the measured spectral + temporal curve, freeze one human-blessed take into constant tables, and re-synthesize at launch (loop the bed, scatter the foreground → never repeats, ~0 KB, no licensing risk). Use when adding ambient/generative audio to an app, game, terminal UI, or site, or on 'add another lofi/rain/ambient sound'…

Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files, including scripts (for example `reference/LOFI-BIBLE.md`, `scripts/analyze_drops.py` and `scripts/analyze_rain.py`).

It sits in Media & Creative, covering Music and audio generation. It works with NumPy. The repository describes itself as: Terminal pixel-art office for AI coding agents. The licence is MIT.

When your agent uses it

  • Adding ambient/generative audio to an app
  • On add another lofi/rain/ambient sound

Example prompts

  • “add another lofi/rain/ambient sound”
  • “/procedural-lofi”

Requirements

  • Python 3

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Audition in a scripting language first (numpy), NOT in your ship language
  2. Reference-fingerprint each sound
  3. Shape synthesis to the measured curve
  4. Human LISTEN gate → freeze the realization
  5. Port + ship (synthesize at launch)

What it can do on your machine

Read from SKILL.md and the folder at commit 96bc06a. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 6 files in scripts/ (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • yt-dlp
    • ffmpeg
    • python3
    • pip
    • cargo

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pip, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Procedural Lofi loads about 3.5k tokens when it runs. Until then it costs about 155 tokens; SKILL.md has 1,921 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~155
When it runs · the whole SKILL.md, loaded when a task matches
~3.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from IvanWng97/pixtuoid at commit 96bc06a, republished under its MIT licence (© IvanWng97). 1,921 words, ~3,510 tokens.

Download SKILL.mdSave it as .claude/skills/procedural-lofi/SKILL.md (or your agent's skills folder). This skill also uses 7 other files; get the full folder from GitHub.
name
procedural-lofi
description
Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships. Fingerprint a beloved reference recording, shape synthesis to the measured spectral + temporal curve, freeze one human-blessed take into constant tables, and re-synthesize at launch (loop the bed, scatter the foreground → never repeats, ~0 KB, no licensing risk). Use when adding ambient/generative audio to an app, game, terminal UI, or site, or on 'add another lofi/rain/ambient sound'. Bundles the parameter tables (LOFI-BIBLE.md) + the numpy fingerprint/synth/freeze pipeline.
version
1.0.0

Procedural Lofi — build a soundtrack in code, not in a sample pack

This skill is the end-to-end recipe for a lofi bed (and its sibling ambient sounds: rain, keystrokes, door chimes, printer, water cooler…) that is synthesized at runtime from constants — zero audio files, zero royalties, and no two minutes ever sound the same.

Two documents ship alongside this one:

  • reference/LOFI-BIBLE.md — the parameter tables. Harmony (chord grammar, voice-leading, register clamps), groove (swing %, drag ms, velocity curves), per-voice sound design (pad / bass / EP keys / sparkle / drums / texture / tape chain), mix targets (band shares, HPF strategy, loudness), and generative lessons from prior art. Every number is cited and, where it conflicts with a measurement, the measurement wins.
  • scripts/ — the Python (numpy) pipeline: analyze_*.py (fingerprint a reference), synth_audition.py (a runnable numpy synth that produces .wav auditions), and export_score.py (freeze a good take into a constants table for the port).

Read those two when you reach the step that needs them. This file is the map.


The core idea (why code, not samples)

A sampled lofi loop is: (a) a licensing liability, (b) heavy to bundle, and (c) audibly repetitive — the human brain catches a loop seam on the 3rd or 4th pass. Synthesizing it solves all three:

  • Legal: acoustic parameters are not copyrightable. You measure a reference to get target numbers (this band has 55% of the power, the centroid sits at 150 Hz, drops land 13 dB above the bed). You never keep or ship the reference bytes. What ships is your own oscillator code hitting those numbers.
  • Size: a few kilobytes of constant tables + a synth function vs. megabytes of PCM.
  • Never repeats (in practice), from three stacked tricks: (1) the frozen musical composition — pad, drums, and the melody (keys + sparkle) — loops in lockstep, but the loop is made long enough that its repetition doesn't fatigue (this project doubled its day loop from 4 to 8 bars precisely because a short looped melody was audibly repetitive — "loop the bed" does not mean "make it short"); (2) the genuinely-stochastic layers — rain drops and keystrokes — are scattered fresh at runtime from a seeded RNG, laid over the loop; (3) a busy-ness stem mixer fades whole stems (drums, keys…) in and out by how active the scene is, so the arrangement keeps changing even though the notes don't. The result reads as "never the same two minutes" without regenerating harmony. (Regenerating melody live is possible but it's the hard, optional part — the shipped product froze the melody and leaned on 1–3 instead.)

The one law of the whole method:

Measurement is the machine's ears; taste is the human's. You (or your tooling) cannot reliably hear whether it sounds good — you can only measure proxies (band energies, onset rate, dB deltas) and drive them to a target. A human listens once per major revision and gives a yes/no. Pick your measurable proxy carefully, iterate on it alone, and hand over a finished audition — don't ask the human to babysit each tweak.


The pipeline (five phases)

Phase 0 — Audition in a scripting language first (numpy), NOT in your ship language

Prototype the whole sound in Python/numpy where the write→hear loop is seconds. Only port to Rust/C++/wasm once a human has ratified the sound. scripts/synth_audition.py is a worked example: deterministic numpy that writes audio-demos/*.wav. Iterating synth recipes in a compiled language first is the classic time sink.

Phase 1 — Reference-fingerprint each sound

For every distinct sound (the lofi bed, rain, typing, each one-shot):

  1. Get a beloved reference. An owner-supplied reference beats a "community ideal" every time — build to what they love, not to what a forum says lofi should be. (yt-dlp / curl for analysis only; for an endless live stream, yt-dlp -g gets the HLS URL, then ffmpeg -t 180 grabs a finite slice.)
  2. Confirm the CHARACTER before deep-matching. One sentence — "gentle rain or heavy downpour?" — saves three wasted versions. On this project, three rain versions were built to the wrong reference (a heavy wash) before the owner clarified they wanted gentle rain.
  3. Fingerprint it. Measure 9 octave-band energies + spectral centroid + rolloff (analyze_rain.py / analyze_typing.py). For anything rhythmic or event-bearing ALSO measure the temporal fingerprint — onset rate, inter-onset-interval spread, per-stroke decay, and the dB level of foreground events vs. the bed (analyze_drops.py). Spectral averages are blind to events: rain's audible drops don't show up in an averaged spectrum at all, only in the temporal pass.
Phase 2 — Shape synthesis to the measured curve

Build your oscillators/noise-shapers and drive their parameters until a re-measurement of your output lands within a few percentage points of the reference fingerprint. The LOFI-BIBLE.md gives you the starting parameter values per voice; the fingerprint tells you which way to push them. Search the literature for the physics (Minnaert resonance for a water glug, inharmonic bar modes 1 : 2.76 : 5.40 for a chime, tape wow/flutter + head-bump for the lofi chain) but tune to the reference, not to the physics ideal.

Phase 3 — Human LISTEN gate → freeze the realization

When the numbers converge, a human auditions once (afplay file.wav on macOS, or hand them the wav). On yes:

The RNG was the composer. Freeze the one take they blessed.

The generative script drew notes/velocities/timings from a seeded RNG. That one seed's output is what got ratified — so capture its exact event stream into constant tables (export_score.py → a .rs / .h table), plus a full-table checksum. Do NOT re-run the RNG in production and hope; a later library bump silently redraws and you ship a different, un-ratified take. The freeze is the contract. (Subtlety: your exporter must reproduce the exact draw order of the original — argument-evaluation order, nested draws inside a choice() — or the frozen table desyncs from what was auditioned.)

Phase 4 — Port + ship (synthesize at launch)

Port the numpy synth to your runtime language reading the frozen tables. Key engineering:

  • The port must be byte-identical to the audition. Keep the ratified fingerprint/ checksum tests; passing them verbatim after the port is your oracle that nothing shifted.
  • No wall-clock reads inside the audio math. Pass dt / now in as parameters. On wasm especially, SystemTime::now() isn't available — and a backgrounded tab that jumps the clock will otherwise ramp-snap your crossfades and burst-replay every queued event (the "stall-clock" bug). Clamp big dt gaps.
  • Loop the frozen composition, scatter only the stochastic layers. All the musical stems (pad/drums/keys/sparkle) tile in lockstep on one loop length — make that loop long enough to not fatigue; then scatter the truly-random layers (rain drops, keystrokes) fresh each frame and fade whole stems by busy-ness (see "Never repeats" above). Tiny RAM: one copy of each stem loop.
  • Keep the sub band clear. The sub-bass register must belong to the bass alone or the low end turns to mud. Two ways to get there: the textbook one is to high-pass every non-bass stem ~140 Hz (LOFI-BIBLE §4); the cheaper one this project used is to voice the other stems out of that register in the first place (mid-register EP plucks; the sub register belongs to the bass lane alone) so there's nothing to filter. Either way, keep ONE texture stem carrying all the "medium" noise — per-stem hiss stacks (every musical stem adding a little sums to real mud); texture sits 25–35 dB below the music.
  • Perceptual volume. Map a user volume slider as amplitude = user² (loudness is logarithmic). Linear volume feels "still too loud at 5%" — the classic trap.

Show full SKILL.md (695 more words)Show less

The failure catalog (bugs this method hit, so you don't)

  • Reference outranks literature. A "thock" keyboard sound built to the ASMR-community ideal measured the opposite of the owner's clacky reference. Search for physics; tune to the reference.
  • Phantom-octave measurement bug. Fingerprints extracted from the listening artifacts (stereo wav, soft-clipped) read every frequency halved (interleaved stereo read as mono = 2× time-stretch). Pin spectral references on the raw float synthesis chain, never on the exported/played wav.
  • Spectral averages can't see events. Rain drops, a snare ghost, a keystroke accent — measure them temporally (level vs. bed, onset rate) or you'll "match" a reference and still be missing its soul.
  • Head-only crossfade ≠ a seamless loop. Fading the start of a loop back over its end leaves the wrap audible. A real seamless loop synthesizes a genuine continuation past the loop point and blends that in.
  • Two frozen copies of one truth desync silently. If a kick-times table duplicates the drum table's kicks, add an equality test or a later edit to one drifts from the other with no error.
  • Control plane off the data plane. A mute/volume press must not ride the same queue as audio frames — a synthesis burst can saturate the queue and eat the keypress, so the beds fade in unmuted while the UI says muted. Put mute/volume on an atomic flag the audio thread reads, separate from the frame channel.
  • Empty-room-uncanny. A truly silent "idle" state feels broken, but a full bed under nothing feels wrong too. Keep the register (don't octave-drop), voice harmonically, sparse EP notes, and let the texture bed carry the quiet — don't drop to pure silence.

Quickstart for a fresh project

  1. Copy reference/LOFI-BIBLE.md and scripts/ into your repo (or just read them).
  2. Install: python3 -m venv .venv && .venv/bin/pip install numpy scipy (+ yt-dlp, ffmpeg for grabbing references).
  3. Pick and character-confirm a reference. Fingerprint it with the matching analyze_*.py.
  4. Adapt synth_audition.py's voices toward the fingerprint; re-measure to convergence.
  5. Human listens once. On yes, export_score.py freezes the take + checksum.
  6. Port to your runtime; keep the fingerprint tests as the byte-identity oracle; synthesize at launch, loop the frozen composition, scatter the stochastic layers, gate stems by busy-ness.

(The scripts/ are the real working prototypes from this project, kept as a concrete starting point — not a turnkey CLI; synth_audition.py runs standalone, and export_score.py imports phase2_audition.py — both are bundled. Adapt the voices to your own reference.)


The GENERATOR loop (pixtuoid's Rust composer — iterate in minutes, not arcs)

Once a project graduates from frozen takes to a theory-constrained generator (pixtuoid-scene/src/audio/compose.rs + synth::gen_beds), the iteration loop changes shape: the LISTEN gate becomes statistical (blind-audition a batch of seeds; all acceptable = the GENERATOR is ratified — a dud = tighten a constraint and re-batch), and every taste axis is a data table or named const with ONE home:

Want to change…Edit (all in compose.rs unless noted)
harmony vocabularyDAY_PROGRESSIONS / NIGHT_PROGRESSIONS (pre-voiced templates + roots_pc + scale_pcs)
tempo feelDAY_BPM / NIGHT_BPM windows
melody characterlead_events rules (density draws, leap bound, peak bar, grid) + *_LEAD_LO/HI registers
groove feelDAY_GROOVES templates / night_drums pattern + the swing/drag consts
comping densitykeys_events density draws
room-tone cracklesynth::CRACKLE_POPS_PER_SEC (one knob, both beds)
a new instrumentsee the checklist below

Add-an-instrument checklist (executed once for the Pluck lead — repeat verbatim):

  1. Write the voice as a pure note fn in synth.rs (fn my_voice(midi, dur_s, vel) -> Vec<f32>), physics-first then tuned by ear/fingerprint (Phase 1-2 of this skill still apply).
  2. Add a compose::LeadVoice variant + its arm in synth::lead_voice_fn (the ONE dispatch).
  3. Give it a draw weight at the END of compose() — the voice draw is deliberately LAST in the seed stream so new voices never redraw an already-blessed seed's notes (one banded unit-draw per mood — re-weight the bands rather than adding draws).
  4. Extend the distribution property test; run the compose suite (fast — no synthesis).
  5. Render a batch (cargo run --release -p pixtuoid-scene --example lofi_audition -- --seeds N; --solo sparkle isolates the lane) → owner listens → tighten or ship.

Mix LANES stay instrument-blind (StemLevels/mixer/players never learn about voices) — a lane is a busy-ness ROLE, an instrument is a timbre WITHIN it. That split is what keeps "blend in another instrument" a minutes-scale edit instead of an arc.

© IvanWng97, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 7 other files (scripts) in .claude/skills/procedural-lofi of IvanWng97/pixtuoid.

  • SKILL.md
  • reference/LOFI-BIBLE.md
  • scripts/analyze_drops.py
  • scripts/analyze_rain.py
  • scripts/analyze_typing.py
  • scripts/export_score.py
  • scripts/phase2_audition.py
  • scripts/synth_audition.py

Open the folder on GitHubat commit 96bc06a

Compare with similar skills

Procedural Lofi next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Procedural Lofi compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Procedural Lofi this skillIvanWng97/pixtuoid490—~3.5kAutomated safety check: PassMIT
Audio Track Production WorkflowHKUDS/OpenSpace7.8k—~2.9kAutomated safety check: PassMIT
Musictadaspetra/loop2962 repos~827Automated safety check: PassMIT
Sound Effectstadaspetra/loop2962 repos~1.1kAutomated safety check: PassMIT
Text To Sfxsonilo-ai/skills1151 repos~1.6kAutomated safety check: NotesMIT
Music Caption RewriterT8mars/T8-penguin-canvas615—~2.2kAutomated safety check: PassMIT

Similar skills

  • Walks through producing a master audio track plus stems in Python, from checking a reference file and timing sections by BPM to effects, a zip archive and final verification.

    7.8k GitHub stars~2.9k tokensUpdated 1 mo ago
    Media & CreativeAuto-check passed
  • Music

    tadaspetra/loop

    Generate music using ElevenLabs Music API. An agent skill from tadaspetra/loop.

    296 GitHub starsUsed in 2 repos~827 tokens
    Media & CreativeAuto-check passed
  • Sound Effects

    tadaspetra/loop

    Generate sound effects from text descriptions using ElevenLabs.

    296 GitHub starsUsed in 2 repos~1.1k tokens
    Media & CreativeAuto-check passed
  • Text To Sfx

    sonilo-ai/skills

    Generate a sound effect from a text description using Sonilo — a UI chime, a whoosh, an impact, ambience, a stylized cue — when there is no video to match.

    115 GitHub starsUsed in 1 repo~1.6k tokens
    Media & CreativeAuto-check: notes
  • Music Caption Rewriter

    T8mars/T8-penguin-canvas

    Turn a brief music description and optional tagged lyrics into a professional MiniMax Music 3 structured caption with Global Metadata, Vocal Details, and a section-aware Arrangement.

    615 GitHub stars~2.2k tokensUpdated yesterday
    Media & CreativeAuto-check passed
  • Video To Music

    sonilo-ai/skills

    Score a video with original music using Sonilo — the model watches the cut and matches pacing, motion, and emotion, returning either the audio or a new video with the score muxed in.

    115 GitHub starsUsed in 1 repo~4k tokens
    Media & CreativeAuto-check: notes

More from IvanWng97/pixtuoid

  • Beautify Decoration

    IvanWng97/pixtuoid

    Iterate on the visual identity of a top-down pixel-art decoration (sprite + layout integration) in pixtuoid.

    490 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Local Review

    IvanWng97/pixtuoid

    Run pixtuoid's review locally at either scope — a DIFF review (one lens per matching REVIEW.md local escalation row; the correctness and design lenses are the CI bots, never re-run locally) or a…

    490 GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Add Source

    IvanWng97/pixtuoid

    Wire a new agent-CLI Source adapter into pixtuoid (a new coding CLI whose sessions become office sprites).

    490 GitHub stars~442 tokensUpdated today
    Auto-check passed
  • Add Theme

    IvanWng97/pixtuoid

    Add a new color theme to pixtuoid (a full Theme palette, rendered into the office).

    490 GitHub stars~449 tokensUpdated today
    Auto-check passed

Works with

Questions about Procedural Lofi

What does Procedural Lofi do?

Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships. Procedural Lofi is an agent skill from IvanWng97/pixtuoid. Generate a royalty-free lofi (or rain / typing / chime / any ambient) soundtrack ENTIRELY in code — no sampled audio ships.

When should I use Procedural Lofi?

Procedural Lofi fits situations like: adding ambient/generative audio to an app; on add another lofi/rain/ambient sound.

How do I install Procedural Lofi in Claude Code?

Run `npx skills add IvanWng97/pixtuoid --skill procedural-lofi -a claude-code`. Or copy the skill folder (.claude/skills/procedural-lofi in IvanWng97/pixtuoid) into .claude/skills/procedural-lofi in your project. Claude Code loads it when a task matches its description.

How do I install Procedural Lofi in Codex?

Run `npx skills add IvanWng97/pixtuoid --skill procedural-lofi -a codex`. Or copy the skill folder (.claude/skills/procedural-lofi in IvanWng97/pixtuoid) into .agents/skills/procedural-lofi in your project. Codex loads it when a task matches its description.

Can I use Procedural Lofi in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add IvanWng97/pixtuoid --skill procedural-lofi -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/procedural-lofi, .gemini/skills/procedural-lofi, .github/skills/procedural-lofi and .opencode/skills/procedural-lofi in your project.

What does Procedural Lofi need to run?

Going by SKILL.md and its folder, Procedural Lofi needs Python for the scripts in its folder and the command-line tools its instructions call (yt-dlp, ffmpeg, python3, pip and cargo). Our summary lists: Python 3.

Does Procedural Lofi access the network?

SKILL.md contains no URLs. Its commands use pip, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Procedural Lofi safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Procedural Lofi use?

Procedural Lofi is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Procedural Lofi use?

About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Procedural Lofi?

Skills that share tags, products or a category with Procedural Lofi: Audio Track Production Workflow (HKUDS/OpenSpace, 7.8k stars), Music (tadaspetra/loop, 296 stars), Sound Effects (tadaspetra/loop, 296 stars) and Text To Sfx (sonilo-ai/skills, 115 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Procedural Lofi?

IvanWng97 (a GitHub user) maintains it in IvanWng97/pixtuoid, which has 490 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 9, 2026.

Source: IvanWng97/pixtuoid on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.