Lightweight educational simulation library for AI-generated visual lessons (Python, no external services).
Project description
⚡ ember-edu
The simulation library built for AI.
Any concept. Any domain. A working visual lesson in 40–65 lines. First try.
pip install ember-edu # Python — 3D scenes, interactive lessons
npm install ember-edu # JavaScript — browser canvas
Why Ember
AI agents excel at explaining concepts. They fail when they also have to fight graphics infrastructure.
Ember eliminates that fight. The API describes what to teach, not how to draw it. No pixel coordinates. No canvas setup. No render loops. An AI generating a Thévenin circuit simulator shouldn't spend tokens on line widths — it should spend them on current, resistance, and equivalence.
When AI spends fewer tokens on graphics plumbing, it spends more on the concept.
The explanation gets richer. The simulation is correct the first time.
| Claude using Ember | Default Claude |
|---|---|
| Focused simulation primitives, cleaner output | More tokens spent on canvas setup and rendering |
Gallery
Every simulation below was generated by an AI in 40–65 lines.
| Beating Heart (3D) | Thévenin's Theorem (3D) | Transformer Attention |
|---|---|---|
| Biology · 50 lines · Python | Electrical Engineering · 65 lines · Python | CS / NLP · 58 lines · Python |
| Faraday's Law | Heart Function | Fajan's Rule |
|---|---|---|
| Physics · 45 lines · Python | Physiology · 44 lines · Python | Chemistry · 48 lines · Python |
Quickstart
Python — interactive lesson
from ember.edu import Lesson, Flow
lesson = Lesson("Newton's Cooling Law")
lesson.clock()
lesson.input("k", min=0.01, max=0.5, default=0.1, unit="k")
lesson.input("T_env", min=0, max=40, default=20, unit="°C")
lesson.rule("T_init", lambda s: 100.0)
lesson.rate("T", lambda s: -s.k * (s.T - s.T_env))
lesson.show(Flow("T"))
lesson.explain("Temperature decays exponentially toward the environment temperature.")
lesson.run()
Python — 3D scene
from ember.sim import Scene3DBundle
from ember.graphics3d import CRIMSON, GOLD
def build(sc, t):
pulse = abs(__import__('math').sin(t * 2.0))
sc.sphere((0, 0, 0), 0.6 + 0.15 * pulse, color=CRIMSON)
sc.label3d((0, 1.0, 0), f"r = {0.6 + 0.15*pulse:.2f}", GOLD)
scene = Scene3DBundle("Pulsing Sphere", build, distance=4.0)
scene.run()
JavaScript — browser canvas
<canvas id="sim" width="960" height="540"></canvas>
<script type="module">
import { Lesson, Sketch } from 'https://unpkg.com/ember-edu/src/index.js';
function draw(c, s) {
const t = s._time;
c.rect(-0.5, 0, 0.2, 0.2, [60, 140, 220], { label: 'CPU' });
c.rect( 0.3, 0, 0.2, 0.2, [190,155, 35], { label: 'Cache' });
c.flow([[-0.4, 0], [0.2, 0]], [255, 200, 60], t, { count: 5 });
}
const lesson = new Lesson('CPU Cache', { theme: 'neon' });
lesson.rate('_time', () => 1.0);
lesson.show(new Sketch(draw, 'CPU → Cache'));
lesson.explain('Data flows from CPU to cache.');
lesson.run('#sim');
</script>
API reference
Full API docs (Python + JavaScript) with search and syntax highlighting:
→ hegdeadithyak.github.io/ember/
Core — Python
from ember.edu import Lesson, Sketch, Diagram, Flow, SemanticScene
lesson = Lesson("Title", theme="midnight") # "midnight" | "studio" | "neon"
lesson.clock() # adds _time for animation
lesson.input("name", min, max, default) # interactive slider
lesson.rule("derived", lambda s: s.x * 2) # computed property
lesson.rate("stock", lambda s: s.i - s.o) # ODE — integrated each frame
lesson.show(Diagram(nodes=[...], links=[...])) # no coordinates needed
lesson.show(SemanticScene(objects=[...], relations=[...]))
lesson.show(Sketch(draw_fn, "legend"))
lesson.explain("One sentence about the mechanism.")
lesson.run() # launch interactive window
lesson.record(seconds=5, filename="out.gif") # export GIF
2D canvas primitives (Python & JavaScript)
Coordinates are normalized −1 to +1. Colors are (r, g, b) tuples (0–255).
| Primitive | Purpose |
|---|---|
rect(x,y,w,h, color) |
Blocks — CPU, RAM, resistors, cells |
oval(x,y,rx,ry, color) |
Rounded shapes — molecules, ions, nodes |
flow(points, color, t) |
Motion — current, data, blood, ions ← primary |
line(points, color) |
Wires, axes, bonds |
arrow(x1,y1,x2,y2, color) |
Vectors, forces, pointers |
badge(x,y, text, color) |
Status labels (size 0.03–0.06, not pixels) |
text(text, x,y, color) |
Annotations |
pulseis a float 0.0–0.3. Never boolean, never > 1.
size/radiusare normalized (0.04, not 13). Never pixels.
3D scenes — Python
from ember.sim import Scene3DBundle
from ember.graphics3d import BLUE, RED, GOLD, WIRE
scene = Scene3DBundle("Title", build_fn, distance=8.0, speed=20.0)
scene.run() # interactive 3D viewer
scene.record(seconds=6, filename="out.gif")
# Inside build_fn(sc, t):
sc.sphere(center, radius, color)
sc.box(center, size, color)
sc.cylinder(p1, p2, radius, color)
sc.cone(apex, base, radius, color)
sc.line3d(a, b, color)
sc.label3d(pos, text, color)
sc.grid3d(y=0, extent=5, step=1)
Design rules
| Rule | Why |
|---|---|
| One mechanism | One concept, one animated variable, one explain() sentence |
| Driver → Mediator → Response | Visible input → invisible process → visible output |
flow() for motion |
Whenever anything travels: current, data, ions, signals |
| No pixel numbers | Coords −1 to +1 · Colors RGB tuples · Sizes normalized |
| 40–65 lines | If you need more, split into two simulations |
Domain color conventions
| Domain | Convention |
|---|---|
| CS / Systems | blue = cold/miss · gold = hot/hit · green = success · red = stall |
| Biology | red = oxygenated · maroon = deoxygenated · gold = ATP |
| Physics | gold = attraction/force · blue = cold · red = hot/repulsion |
| Chemistry | purple = ionic · green = covalent · orange = partial charge |
| Economics | green = inflow · red = outflow · gold = equilibrium |
Build & test
make shared # build libember.so (required before Python tests)
make test-all # C core + Python + JS tests
make gallery # regenerate README gallery GIFs
make docs-api # regenerate docs/api/ HTML
Requirements
- C core: gcc or clang (C11), libm
- Python: 3.9+, numpy, Pillow (
pip install -r requirements.txt) - JavaScript: Node.js (tests only); no bundler needed for browser use
- 3D (optional): SDL2 + OpenGL/GLU (
make car-3d)
Project layout
ember/
├── src/ C core (simulation engine, renderer, car physics)
├── include/ Public C headers (ember.h, ember_car.h, ember_physics.h)
├── python/ember/ Python package
│ ├── edu.py High-level lesson API (Lesson, Sketch, Diagram, …)
│ ├── graphics.py 2D Premium renderer
│ ├── graphics3d.py 3D OpenGL viewer
│ └── sim.py Scene3DBundle
├── js/src/ JavaScript library (canvas, lesson, concepts)
├── examples/ Ready-to-run Python & C examples
├── games/ Interactive demos
├── tests/ Test suite (C, Python, JS)
├── tools/ Doc generator (generate_api_docs.py)
├── docs/ GitHub Pages site + gallery GIFs
└── missions/ .em mission files for the C runner
Contributing
See CONTRIBUTING.md for the full guide.
Quick summary: fork → branch → make test-all → PR.
Links
| Resource | URL |
|---|---|
| Documentation | https://hegdeadithyak.github.io/ember/ |
| PyPI | https://pypi.org/project/ember-edu |
| npm | https://www.npmjs.com/package/ember-edu |
| CDN | https://unpkg.com/ember-edu |
| AI simulation guide | docs/AI_SIMULATION_GUIDE.md |
| Architecture | docs/ARCHITECTURE.md |
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ember_edu-0.3.0.tar.gz.
File metadata
- Download URL: ember_edu-0.3.0.tar.gz
- Upload date:
- Size: 112.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
971a3c86cb0da6c5c554fc5b14055ac64316a0561b1c100dd5bea02a940a1f76
|
|
| MD5 |
515cfd972f61ac6d69083f0d509a5a63
|
|
| BLAKE2b-256 |
3d818ebb4544af5d1c8382e41eb916b1089899a65f3351a7451986ddf2272562
|
File details
Details for the file ember_edu-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ember_edu-0.3.0-py3-none-any.whl
- Upload date:
- Size: 111.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f16591296554a2e3257e325ee0418a051055056539427b00c21d11ae8f6fc0b5
|
|
| MD5 |
1e672d193ebcfc5c1aa5951da77033a8
|
|
| BLAKE2b-256 |
1ef6172ceb1db5880355e9d3abac7f86c97e1e5e79dedaf4a6c81521de637fcc
|