$npx -y skills add thtskaran/claude-skills --skill ml-contentGenerate publication-grade ML explainer videos and carousels the way 3Blue1Brown actually builds them — in real manimGL (NOT Manim Community Edition), as a tiny domain DSL of self-arranging Mobjects choreographed into transform-driven beats where every motion carries meaning. Ove
| 1 | # ml-content |
| 2 | |
| 3 | Generate ML explainer content that looks like 3Blue1Brown, not like AI slop. |
| 4 | |
| 5 | > ## ⚠️ PRIME DIRECTIVE — treat every video as nuclear. ZERO errors ship. |
| 6 | > The content goes public to an audience that **will** fact-check it. A single wrong number, mislabeled quantity, or overstated claim destroys trust in everything else and gets screenshotted. So: **nothing — not even slightly — may be wrong.** Every spoken line, every on-screen number and label, every caption, and the thumbnail must be **verified against the primary source before it is rendered, and audited again on the rendered video before it ships** (§10, the non-negotiable gate). If you cannot cite the exact source line for a claim, you do not say it, write it, or put it on screen. Soften it or cut it. **No "dramatic license" on numbers.** When in doubt, it is wrong until proven right. |
| 7 | |
| 8 | This skill was rebuilt from a full read of **Grant Sanderson's actual production code** (`github.com/3b1b/videos`, 503K LOC, 2015→2026) and **the real manimGL engine** (`github.com/3b1b/manim`). Every rule below is grounded in that source with `file:line` citations. Where this skill once guessed, it now measures. |
| 9 | |
| 10 | **The video engine is manimGL** (the 3b1b version), driven by `manimgl`. Manim Community Edition (CE) is a *different library with a different, incompatible API* — code written for one crashes on the other. Static IG carousels use HTML/matplotlib (see the Carousel section); everything animated is manimGL. |
| 11 | |
| 12 | --- |
| 13 | |
| 14 | ## 0. Why the old output was slop (read this once) |
| 15 | |
| 16 | The previous version of this skill produced overlapping elements, weak animation, no consistency, and infographic-feeling stills. The root causes, now fixed: |
| 17 | |
| 18 | 1. **It shipped Manim CE code while preaching manimGL.** The old template used `from manim import *`, `MathTex`, `ThreeDScene`, `set_camera_orientation`, `set_fill_by_value`, `Create`, `begin_ambient_camera_rotation` — **none of which exist in manimGL** (`grep` over the entire engine = 0 hits). It would not even run. |
| 19 | 2. **100% of real output was actually built in matplotlib**, hand-placing ~57 text calls + ~20 boxes per scene with absolute coordinates. That is the worst possible tool for animation: no relative layout, no transform system, no camera. Overlap is guaranteed. |
| 20 | 3. **It treated overlap as a validation problem** (bbox asserts, frame validators, ffmpeg caption-pads) instead of a *construction* problem. 3b1b never validates overlap — it makes overlap structurally impossible by building self-arranging objects. |
| 21 | 4. **It treated motion as decoration.** Elements faded in from nowhere as disconnected islands. In real 3b1b, objects are *born from the thing they abstract* (`TransformFromCopy`), so every motion teaches. |
| 22 | 5. **Planning was marketing copy with word-count targets.** Real 3b1b planning is an ordered list of named teaching beats that reads top-to-bottom as the narration. |
| 23 | |
| 24 | The fix is a different mental model, encoded as the Six Laws below. |
| 25 | |
| 26 | --- |
| 27 | |
| 28 | ## 1. The engine reality (the single most important section) |
| 29 | |
| 30 | **Start every manim file with:** |
| 31 | ```python |
| 32 | from manim_imports_ext import * # in the 3b1b/videos repo |
| 33 | # or, standalone: from manimlib import * |
| 34 | ``` |
| 35 | |
| 36 | **Scene base class is `InteractiveScene`** (`interactive_scene.py:66`) — for 2D *and* 3D. In the entire 2025 corpus: `InteractiveScene` subclassed 385 times, `ThreeDScene` (`scene.py:930`) 0 times — it exists but 3b1b never uses it. 3D is achieved on an `InteractiveScene` by moving `self.frame`. |
| 37 | |
| 38 | **The camera is `self.frame`** (a `CameraFrame` mobject; `scene.py:112`). Local alias `frame = self.frame` appears 114× in 2025 code. `self.camera.frame` appears 0×. |
| 39 | |
| 40 | **Render / iterate:** |
| 41 | ```bash |
| 42 | manimgl file.py SceneName # render |
| 43 | manimgl file.py SceneName -se 120 # drop into IPython at line 120 (the dev loop) |
| 44 | manimgl file.py SceneName -w # write to file |
| 45 | # inside the embed: checkpoint_paste() runs clipboard code with checkpoint rewind |
| 46 | ``` |
| 47 | |
| 48 | ### CE landmines — Table A: these genuinely CRASH on manimGL (absent symbols) |
| 49 | |
| 50 | | You must NOT emit (CE) | Use instead (manimGL) | Evidence | |
| 51 | |---|---|---| |
| 52 | | `from manim import *` | `from manim_imports_ext import *` / `from manimlib import *` | CLAUDE.md:59 (loads the wrong library) | |
| 53 | | `MathTex(...)` | `Tex(...)` | grep MathTex over repo = 0; CLAUDE.md:82 | |
| 54 | | `self.set_camera_orientation(phi=,theta=,zoom=)` | `self.frame.reorient(theta, phi, gamma, center, height)` | absent; `camera_frame.py:172` | |
| 55 | | `self.move_camera(...)` | `self.play(self.frame.an |