Grayson’s Song  •  App Comparison  •  10/19/2026
TNT — Creative Coding & Cross Training  •  Grayson’s Song Stage 2

⭐ 🌚 Grayson’s Song:
Three Languages, One Night Sky

The same professionally documented animation — named constants, modular functions, and JSDoc comments — in JavaScript (p5.js), Java Processing, and Python Processing, side by side.

The Ideas

Seven Concepts at Work in Every Version

The Processing vocabulary is the same in all three languages. What changes is how each language handles constants, state, transforms, and function scope.

Named Constants

Every magic number is replaced by a named constant. How each language declares an immutable value differs: JS uses const, Java requires final type, and Python uses UPPER_CASE by convention only.

const NAME = vfinal type NAME = vNAME = v (UPPER)
randomSeed() + Phase Offset (Twinkling)

randomSeed(STAR_SEED) resets the generator each frame so star positions never change. Adding ndx to the sin() argument shifts each star to a unique phase — 400 independent twinkles from one formula.

identical APIsame functionsame function
HSB Color Mode

colorMode(HSB, 360, 100, 100, 100) is identical in all three versions. Named constants like SKY_H = 235 make the color palette self-documenting and easy to change across any language.

identical valuessame APIsame API
Background-Color Cutout (Crescent Moon)

A crescent is made without arcs: draw a full circle in moon color, then overlay a smaller circle in sky color offset to the right. The sky-colored circle erases part of the moon. The technique is identical in all three versions.

circle() × 2circle() × 2circle() × 2
Transform Stack

The central star uses translate, rotate, and scale simultaneously. JS uses push()/pop() to isolate the transforms. Java and Python Processing require pushMatrix()/popMatrix().

push()/pop()pushMatrix()pushMatrix()
Polar Geometry (drawStar)

The custom star function alternates between outer and inner vertices at angles derived from dividing TWO_PI by n. -HALF_PI puts the first point at 12 o’clock. The math is identical in all three.

a = -HALF_PI + ndx * sectorAngle
vertex(cos(a) * r2, sin(a) * r2)
State Variables & Global Scope

Mutable state (moonX, starHue) is kept separate from constants. JS uses let. Java declares typed class-level variables. Python uses module-level variables and requires global inside functions that modify them.

let moonXfloat moonXglobal moon_x

All Three Versions, Side by Side

Yellow paper = JavaScript  •  Blue paper = Java  •  Green paper = Python. Each panel scrolls independently. Use the Copy button to copy clean source into your IDE.

JavaScript graysonsSongStg2Sketch.js
    Java graysonsSongStg2.pde
      Python graysonsSongStg2.py
        ℹ️ Copying into a Processing IDE: Use the Copy button above each panel — it copies the raw source string directly from the JavaScript variable, not from the rendered display. This ensures no HTML markup, keyword-highlight spans, or entity characters are included. Paste directly into the Processing IDE or the p5.js Web Editor.

        What Changes Across the Three Versions

        The core Processing vocabulary is identical in all three: background(), fill(), circle(), ellipse(), text(), rotate(), randomSeed(), random(), sin(), map(), TWO_PI, HALF_PI, and colorMode(HSB, 360, 100, 100, 100). Every constant name and every scene function name is the same in all three sketches.

        The interesting language differences: JavaScript uses const for block-scoped immutable bindings; Java requires final type NAME with an explicit type for every constant; Python uses UPPER_CASE as a convention — the runtime does not enforce immutability. Java additionally requires a settings() method (Processing 3+) to call size() with named constants — setup() only accepts integer literals there. Python requires a global declaration for any module-level variable modified inside a function (moon_x, star_hue); JavaScript and Java handle this automatically. And Java’s draw_moon() modifies the class-level moonX float without any special declaration.

        Push/pop: JavaScript uses push()/pop(); both Java and Python Processing require the older pushMatrix()/popMatrix(). The net effect is identical: the transform stack is saved before and restored after the central star’s translate/rotate/scale, so the moon, hills, and text are unaffected.

        One sketch, three dialects. The named constants make the night sky the same in every classroom.  •  Chat Log documents the decisions that produced this comparison.