2500 Logo

a dynamic-turtle logo, after the TT2500  ·  plates that spin, move & grow
origin · heading ↑
● live
 
save or exact frames s @ fps, × px, ss
 
example
program  ·  the first procedure runs (or top-level commands, if any)

move the turtle

FD / BK n
forward / back n steps (draws a vector)
RT / LT n
turn right / left n degrees
PU / PD
pen up / pen down
HM
home — back to origin, facing up
PEN hue
pen colour by hue 0–360° — wraps (e.g. 400 → 40); ~120 green, ~210 blue, ~300 magenta
PEN hue sat light
full HSL: hue 0–360° (wraps), saturation & lightness 0–100 (clamped)
WIDTH n
pen width in steps (min 0.2)

open a moving plate (these nest)

SPIN r
rotate the plate, r°/sec
MOVE r
slide it forward, r steps/sec (unbounded)
GROW f
scale ×f every second (1 none, >1 grow, <1 shrink; compounds)
WAG a p
rock rotation ±a° every p sec
BOB a p
slide forward ±a every p sec
PULSE a p
breathe scale ±a every p sec
HUESHIFT r
rotate hue r°/sec; optional HUESHIFT r sat light drifts saturation & lightness /sec

structure

TO … END
define a procedure (:name for inputs)
REPEAT n […]
repeat a block n times
IF c THEN …
conditional (optional ELSE; […] for blocks). Compare with = < >
STOP
leave the current procedure
; …
a comment, to the end of the line (anywhere)

The first procedure runs automatically. Or, like classic Logo, put a call below the last END (e.g. FOO 5 1 .5) and that runs instead — handy for procedures that take inputs. A recursive procedure needs a base case (an IF … THEN STOP) or it runs until the vector cap.

Everything drawn after you open a plate rides that plate, and plates nest — a plate on a plate gives epicyclic motion. Static FD/RT lay down rigid geometry; the program runs once to build a display list, then it is re-drawn every frame at the current time. ⌘/Ctrl + Enter runs.

+ New starts a blank program (examples stay in the menu). Trails stops clearing the screen so moving parts paint their paths. Plates overlays a disc on every moving frame, coloured by kind: spin · move/bob · grow/pulse · wag · hueshift — the tick marks each plate's current heading.

Arithmetic is plain infix. A minus with spaces on both sides is subtraction (:N - 1); a minus tucked against a number is negative (HUESHIFT 0 -40 0 passes −40). No parentheses needed for negative arguments.

⏺ Record grabs a .webm in real time, so under heavy load (e.g. FOO) it drops frames. ⬇ .zip renders every frame at exactly t = frame ÷ fps regardless of how long that takes — a perfectly even frame rate — then ffmpeg assembles them.