The example catalog: 119 raylib demos in jolt

A map of the whole suite. Each example is one namespace under src/net/b12n/raylib_jlt/, runnable by a friendly bb <name> task or the underlying jolt -M:<alias>. bb info prints this grouping live; this page adds the "how it's wired" recipe at the end.

Run one, list them, or reel through all of them:

bb <name>          # e.g. bb asteroids   (opens a window)
bb examples        # flat list with descriptions
bb info            # the grouped cheat-sheet below
bb run-all [secs]  # every example, N seconds each (unattended)

games (10)

previewbb nameshows
asteroidsthe classic vector shooter, splitting rocks
tetris10×20 well, 7 tetrominoes, lines, levels
pongtwo-paddle classic, you (W/S) vs a CPU
vampire-survivorsauto-firing survivors-like: waves, XP, levels
snakethe classic snake (arrow keys, grow, don't crash)
breakoutpaddle + ball + brick grid (mouse paddle)
space-invadersmarching aliens (arrows + SPACE to shoot)
flappy-birdflap through the pipe gaps (SPACE)
game-20482048: 4x4 tile-merge puzzle (arrow keys)
minesweeperreveal/flag grid (mouse L reveal, R flag)

core (23)

previewbb nameshows
basic-windowthe minimal window + text (jolt -M:run)
input-keysIsKeyDown, steer a ball with the arrow keys
input-mouseGetMouseX/Y + click to recolor
input-mouse-wheelGetMouseWheelMove scrolls a box
camera-2da 2D camera over a skyline (struct by value)
delta-timeper-frame vs GetFrameTime movement
scissor-testBeginScissorMode clips a grid
basic-screen-managera LOGO / TITLE / GAMEPLAY / ENDING state flow
random-valuesGetRandomValue, a new value every 2s
window-letterboxa fixed picture letterboxed into the window
window-flagstoggle vsync/resizable/topmost live
monitor-detectorevery attached display, current one lit
clipboard-texttype, C copies to the system clipboard, V pastes
input-gamepadlive sticks, triggers and buttons for gamepad 0
input-multitouchtouch points (the mouse is point 0)
input-virtual-controlsan on-screen D-pad and action button
undo-redoa bounded history, CTRL-Z and CTRL-Y walking it
window-should-closeSetExitKey so a close request can be answered
input-gesturesGetGestureDetected, named as they happen
random-sequencea shuffled sequence, each height used once
camera-2d-mouse-zoomzoom pinned to the point under the cursor
storage-valuesvalues that survive a restart, via a file
camera-2d-platformerfive ways a camera can follow a jumping player

shapes (42)

previewbb nameshows
bouncing-ballanimation, IsKeyPressed pause, DrawFPS
basic-shapesrect / circle / ellipse / line + an rlgl triangle
colors-paletteevery named raylib color in a grid
gradientDrawRectangleGradientV (two by-value Colors)
following-eyespupils track the mouse (scalar trig)
starfieldGetRandomValue + bulk draw, per-star twinkle
logo-raylibrectangles + text, positioned with MeasureText
mouse-traila fading cursor trail (alpha)
recursive-treea binary fractal tree (lines + trig)
math-sine-cosinea live unit-circle sine/cosine visualization
bullet-hella rotating bullet spiral
triangle-stripa rainbow strip via rlgl immediate mode
collision-areaAABB collision between two boxes
dashed-linea dashed line follows the mouse
double-pendulumchaotic double-pendulum motion + trail
kaleidoscopestrokes mirrored with 6-fold symmetry
hilbert-curvea rainbow Hilbert space-filling curve
math-angle-rotationfixed spokes + a spinning line
ball-physics2D balls under gravity, SPACE respawns
lines-beziera cubic Bézier that follows the mouse
color-wheelan HSV wheel as an rlgl triangle fan
pie-chartlabelled pie slices via rl/sector! + a legend
splinesCatmull-Rom / Bézier / B-spline (SPACE cycles)
vector-anglethe signed angle between two vectors (atan2)
easingsa grid of balls, each on a different easing
penrose-tilinga P3 Penrose tiling by golden-ratio deflation
analog-clocka live analog clock (libc local time)
digital-clocka seven-segment HH:MM:SS display
ring-drawingan animated annulus via rl/ring!
rounded-rectanglerounded rects from sector! corners
rectangle-scalingdrag the corner handle to resize a rect
lines-drawinga rotating fan of thick rl/line-ex! lines
ellipse-collisiontwo ellipses reddening when they overlap
rlgl-triangleper-vertex colour interpolated across a face
rlgl-color-wheela hue wheel as a triangle fan
circle-sector-drawinga sector starved of segments
easings-rectanglessize and rotation on one easing curve
easings-ballslide, swell and fade, one curve each
easings-boxdrop, flatten, spin, grow, fade: five curves
logo-animthe raylib logo assembling itself, unsmoothed
rectangle-advancedper-side roundness with a horizontal gradient
easings-testbedone curve at a time, plotted and run

text (5)

previewbb nameshows
font-sizesfont sizes + MeasureText centering
writing-anima self-typing message
format-textformat padded score + MM:SS timer
words-alignmentalign a word inside a box with MeasureText
input-boxtype into a text box (GetCharPressed)

3d (16)

previewbb nameshows
camera-3dan orbiting 3D camera, Camera3D by value
waving-cubes196 cubes rippling in 3D (shared rl/cube!)
camera-3d-first-personWASD + mouse-look walk through columns
tesseract-viewa rotating 4D hypercube projected 4D→3D→2D
wireframe-shapespyramid / torus / helix as rlgl 3D lines
rlgl-solar-systemSun / Earth / Moon via the rlgl matrix stack
box-collisionsa player cube vs. boxes, 3D AABB highlight
rotating-cubea single cube spinning via the rlgl matrix stack
spinning-cubesa row of cubes each spinning with a phase offset
orthographic-projectionperspective vs orthographic (SPACE toggles)
point-cloud~1500 points as tiny rlgl cubes, rotating
bouncing-spheresspheres bouncing in a 3D box (rl/sphere!)
lorenz-attractorthe Lorenz attractor traced in 3D
dna-helixa turning double helix with coloured base pairs
yaw-pitch-rollthe three aircraft rotations in 3D
first-person-mazewalk a grid maze in first person, with a minimap

The 3D set stands entirely on two building blocks from rlgl-immediate-mode.md and struct-by-value-pointer-trick.md: with-camera-3d (the camera, by pointer) and cube! (the geometry, by rlgl vertices).

generative (9)

previewbb nameshows
game-of-lifeConway's Game of Life (SPACE reseeds)
boidsflocking birds (separation/alignment/cohesion)
fireworksrockets + fading particle bursts
fourier-epicyclesrotating circles trace a square wave
spirographanimated hypotrochoid roulette curves
l-systeman L-system fractal plant (grows + regrows)
flow-fieldparticles steered by a flow field (trails)
cellular-automataWolfram's elementary automata
clock-of-clockssix digits spelled by a grid of clock hands

All eight are pure math + the drawing API, no new bindings. They showcase the suite as a generative-art canvas: cellular automata, agent flocking, particle systems, rotating-vector Fourier series, parametric roulette curves, string-rewrite fractals, and noise-steered flow fields.

textures (4)

raylib's texture API returns structs by value and has no binding here; these go through rlgl's scalar layer instead, so every texture is built pixel by pixel in native memory rather than loaded from a file. See textures-via-rlgl.md.

previewbb nameshows
texture-proceduralfour textures built pixel by pixel
texture-tilingone tile repeated across the window
render-texturea scene drawn off-screen, then reused
bunnymarkthe sprite-count benchmark (click to add)

shaders (10)

GLSL compiled at runtime and run over a full-screen quad. raylib's LoadShader returns a Shader by value, which needed jolt's [:by-value [:struct ...]] - so these are the first examples with a hard jolt floor (0.7.23). The source lives as a string in each namespace rather than a .glsl file, so an example stays one self-contained file.

That [:by-value ...] support also supersedes the workarounds described in textures-via-rlgl.md and struct-by-value-pointer-trick.md; those pages still describe what the suite currently does elsewhere. A page on the by-value API itself is not written yet.

previewbb nameshows
julia-setthe Julia set, mouse-steered, in a shader
mandelbrot-setthe Mandelbrot set, zoomable, in a shader
raymarchinga raymarched SDF scene in a shader
rounded-rect-shaderSDF rounded rects: fill, border, shadow
palette-switchbands recolored by an ivec3 palette
shader-hot-reloadswap and recompile the GLSL at runtime
postprocessingpost-process shaders cycled over a scene
custom-uniforma mouse-steered swirl over a scene
texture-paintinga blank texture painted by a shader
multi-samplertwo textures blended by a second sampler

Adding an example: the five touchpoints

The suite is deliberately mechanical to grow. One new example touches five places:

  1. Source: src/net/b12n/raylib_jlt/<name>.clj, a namespace with a -main that runs the canonical loop (see headless-smoke-testing.md) against the net.b12n.raylib-jlt.raylib API.
  2. deps.edn alias: :<name> {:main-opts ["-m" "net.b12n.raylib-jlt.<name>"]} so jolt -M:<name> works.
  3. check.clj require: add net.b12n.raylib-jlt.<name> to the :require list in net.b12n.raylib-jlt.check, so the headless compile-check covers it.
  4. Registry row: add ["<display-name>" "<alias>" "<group>" "<desc>"] to the examples vector in scripts/examples_registry.clj, the single source of truth that bb.edn and the demo recorder both read.
  5. bb.edn task: add a matching <name> {:doc "..." :task (run-example "<name>")} row, so bb <name> works alongside bb info / bb examples / bb run-all.

bb check:registration verifies all five without needing jolt or libraylib, and CI runs it before the compile gate. Touchpoint 3 is why it exists: bb check compiles what check.clj requires, so an example missing from that list is never compiled and the run still reports success.

Note that the alias is not always the display name, and the namespace is derivable from neither. ["basic-window" "run" ...] reaches net.b12n.raylib-jlt.core through the :run alias, and twelve rows differ this way, so deps.edn is the source of truth for which namespace a row means.

A new group needs two more edits: the group list in bb.edn's info task and the :groups vector in scripts/demo_manifest.edn.

flowchart LR
  src["src/…/<name>.clj<br/>the example"] --> deps["deps.edn<br/>:<name> alias"]
  src --> chk["check.clj<br/>require (headless compile)"]
  src --> reg["scripts/examples_registry.clj<br/>registry row"]
  reg --> bb["bb.edn<br/>bb &lt;name&gt; task"]

Filenames use underscores (basic_screen_manager.clj); the namespace uses hyphens (net.b12n.raylib-jlt.basic-screen-manager), Clojure's standard file↔ns mapping.

One ordering rule applies inside every file: since jolt 0.4.0 an unresolved symbol is a compile error rather than a late-bound reference, so a definition must appear before its first use, in a fn body and in an :or destructuring default just as much as at top level. It bites hardest in the shared raylib.clj binding layer, where one misordered symbol stops every example from loading and only the first offender is reported. jolt -M:check is the quick confirmation; see the jolt note in the README.

See also