Tutorial: Visual Grammar 101 — Step 0/9 (initialising)
R name ( min max ) — define a variable range (e.g., R len ( 0.15 0.3 )).
T ( x y z ) — translate position in 3D space.
S ( sx sy sz ) — scale (uniform or per-axis).
A ( degrees axis ) — rotate by degrees around axis (0=X, 1=Y, 2=Z).
D ( sx sy sz ) — scale cube dimensions in x/y/z.
DS ( sx sy sz ) — dynamic scale based on iteration variables.
I ( Cube | CubeX | CubeY | Sphere | Cylinder … texture scale ) — instantiate primitive with texture and scale.
RuleName repeat vars… -> body. Use R* for random variables. Transform stack: [ push, ] pop, | separator.
R* varName ( min max ) creates iteration variable. Reference in expressions like 360/N*k.
S ( 1 2 3 ) · [ Y ] / ❌ S(1 2 3) · [Y]
Start 1 -> [ T ( 0 1 0 ) I ( Cube metal 0.5 ) ]Radial -> R* N ( 8 12 ) RadialInitRadialInit 1 N -> R* k ( 0 N/2 ) RadialCore
metal, wood, glass, stone, plastic, concrete, marble, and 50+ more presets.
The application follows a modular architecture:
GrammarLexer, Grammar, MathParser, MathTokenizerAnalysisEngine, Token, Rule, VariableContext, Scope, Scene, SolutionWebGLSceneRenderer, RendererManagerEditorApplication, ConsoleManager, TutorialManagerMat4, Vec3, Axis, MathExpressionEvaluatorParseError, RuntimeGrammarError, SolutionErrorTEXTURE_PRESETS - Texture preset definitionsSTRUCTURE_PRESETS - Structure presetsGRAMMAR_TOOLTIPS - Grammar tooltipsTRI_IDX - Triangle indicesEDGE_IDX - Edge indicesCUBE_TRI_UVS - Cube triangle UVsFS_LIT - Fragment shader (lit)VS_LIT - Vertex shader (lit)constructor(canvasOrSelector, opts={}) - Initializes renderersetScene(scene) - Sets scene to renderinvalidate() - Invalidates renderrender() - Renders sceneresize() - Resizes canvascreateAllPresetTextures() - Creates texturesgetTexture(name) - Gets texturesetWireframe(on=true) - Sets wireframe modesetLineColor(r=0, g=0, b=0, a=0.3) - Sets line colorconstructor() - Initializes sceneadd(type, transform1, transform2, transform3, texIndex, arg, val, axisName = "z") - Adds objectclear() - Clears scenegetAll() - Gets all objectsconstructor(fileText) - Parses grammar from textMathS(input) - Processes math expressionsReadTokens(rule, rule_str, sec) - Reads tokens from ruleRecurse(rule) - Recursively processes rulefindRule(name) - Finds rule by nameexpectOp(S, op, ctx = "syntax") - Expects operatorisNumStr(s) - Checks if string is numberconstructor(text) - Initializes lexer_lex() - Performs lexical analysis_matchArrow(i) - Matches arrow operator_matchMath(start) - Matches math expression_readIdentifier(s, i, end) - Reads identifier_readNumber(s, i, end) - Reads numberanalyze(text, caretPos = 0) - Analyzes grammar text at caret positiontokenize(text) - Tokenizes grammar textrunDiagnostics(text, tokens) - Runs diagnostics on grammarcollectSymbols(text) - Collects symbols from grammar textbuildRuleIndex(text, tokens, ruleNames) - Builds index of grammar rulesconstructor(elements = null) - Creates matrixidentity() - Sets to identitytranslate(x, y, z) - Translates matrixscale(x, y, z) - Scales matrixrotateX(angle) - Rotates around XrotateY(angle) - Rotates around YrotateZ(angle) - Rotates around Zmultiply(other) - Multiplies matricesinvert() - Inverts matrixtransformPoint(point) - Transforms pointtransformDirection(direction) - Transforms directiongetNormalMatrix() - Gets normal matrixtoFloat32Array() - Converts to Float32constructor(x = 0, y = 0, z = 0) - Creates vectoradd(other) - Adds vectorssub(other) - Subtractsmul(other) - Multipliesdiv(other) - Dividesdot(other) - Dot productcross(other) - Cross productmagnitude() - Gets magnitudenormalize() - Normalizesscale(x = 1, y = 1, z = 1) - ScalesdistanceTo(other) - Distance tolerp(other, t) - Linear interpolationconstructor(kind = "z") - Creates axis (x, y, or z)applyTransform(M) - Applies transformation matrixtoFlat32() - Converts to Float32Arrayconstructor(other = null) - Creates scopeT(v) - TranslateS(v) - ScaleRx(angleDeg) - Rotate XRy(angleDeg) - Rotate YRz(angleDeg) - Rotate ZDS(v) - Dynamic scaleDT(v) - Dynamic translateapply(M) - Applies matrixgetTransform() - Gets transformgetTransform2() - Gets secondary transformgetTransform3() - Gets tertiary transformconstructor(variables={}, functions={}) - Initializes evaluatorconstructor() - Initializes contextcurrent() - Gets current contextpush() - Pushes contextpop() - Pops contextpushScope() - Pushes new scopepopScope() - Pops scopegetCurrentScope() - Gets current scopenewScope() - Creates new scopeconstructor(name, instCount=0) - Creates tokenaddArgument(v) - Adds argumentaddInstanceType(s) - Adds instance typesetVarName(s) - Sets variable nameisRule() - Checks if ruleperformAction(context, scene, deps = {}) - Performs actionprint() - Prints tokenconstructor(name, repeat) - Creates ruleaddToken(tok, sec) - Adds token to ruleprint() - Prints ruleconstructor(name, min, max, i) - Creates variablegetRandom() - Gets random valueconstructor() - Initializes applicationinitialize() - Initializes applicationinitializeUI() - Initializes UIrunGrammar() - Runs grammarrender() - Renders editorsetupEventListeners() - Sets up listenerstoggleOrbit() - Toggles orbitconstructor(outputElement) - Initializes console managerinfo(t) - Logs info messagewarn(t) - Logs warning messageerror(t) - Logs error messagerenderLine(type, text) - Renders console lineprepare(tokens, scene) - Prepares tokens for executiontransformGrammar(program) - Transforms grammarmakeStructure(type, axis, name, vars) - Makes structurereplacevars(s) - Replaces variables in stringMathS2_js(input) - Evaluates math expressionscollectRuleBlocks(src) - Collects rule blockssplitBlock(block) - Splits block into partsprogram(gl, vs, fs) - Creates shader programcompile(gl, type, src) - Compiles shadertransformPoint(M, v, w) - Transforms pointmakeRng(seed) - Creates RNGpickWeighted(entries, rnd) - Weighted random pickbuildProgram({preset, count, axisBias, scale, center, baseVars}) - Builds programconstructor(message, line = 0, col = 0, snippet = "") - Creates parse errorconstructor(message) - Creates runtime errorconstructor(message, idx = -1, expr = "") - Creates solution errorconstructor(consoleManager) - Initializes rendererinitialize() - Initializes rendererrunGrammarPipeline(text, statusCallback) - Runs grammar pipelinetoggleOrbit() - Toggles orbit modeclear() - Clears sceneconstructor(consoleManager) - Initializes tutorialinitialize(sourceElement) - Initializes tutorialcreateDemoGrammar() - Creates democreateTutorialButton() - Creates buttonupdateHeader(stepIndex, total, title, completed = false) - Updates headerHere are versatile structure archetypes you can generate and combine, each with tunable variables and axis alignment (0 = X, 1 = Y, 2 = Z). These map well to procedural grammars like the ones we’ve been building.
Description: Instances radiate around a central axis at equal angular intervals.
Good for: Hubs, starbursts, antennas, petals.
Key vars: N (count), R (radius), axis, element scale.
Description: A closed loop of instances arranged around an axis.
Good for: Wheels, collars, stadium tiers.
Key vars: N (segments), R (major radius), scale, axis.
Description: A line of instances distributed along a span.
Good for: Facades, ribs, tracks.
Key vars: N (segments), span length, deformation mod, axis.
Description: Repeating instances ascending along an axis.
Good for: Towers, pagodas, pillars.
Key vars: H (levels), step height, taper profile, axis.
Description: N×N arrays on a plane.
Good for: Floors, facades, shelving.
Key vars: G (grid size), cell spacing, layering depth, axis orientation.
Description: Multiple rings stacked along an axis.
Good for: Amphitheaters, turbine cages.
Key vars: rings (count), per-ring N, vertical step, scale ramp.
Description: A band that winds around an axis with pitch.
Good for: Stairs, DNA-like towers, ramps.
Key vars: turns, pitch, radius ramp, axis.
Description: Splits a band/stack into multiple offspring.
Good for: Trees, branching frames.
Key vars: depth, branching factor, divergence angle.
Description: Concentric rings × radial spokes.
Good for: Plazas, solar farms.
Key vars: ring count, spokes count, ring spacing.
Description: Band sampled along a spline.
Good for: Bridges, ornament, aerodynamic skins.
Key vars: curve function, thickness, twist, tessellation.
Description: Stack with shrink factor per level.
Good for: Ziggurats, skyscrapers.
Key vars: floors, shrinkFactor, floorHeight.
Description: Band/grid combo forming window rows/columns.
Good for: Buildings, wall systems.
Key vars: band N, grid G, window spacing, mullion thickness.
Description: Grid with arched/ring elements.
Good for: Halls, canopies.
Key vars: span, arch height, axis.
Description: Spokes + ring stack with upward bending.
Good for: Pavilions, umbrellas.
Key vars: spokes N, rings, curvature, axis.
Description: Ring where each element emits a smaller ring.
Good for: Filigree, fractal frames.
Key vars: recursion depth, child scale, angle jitter.
Description: L-system lines mapped to instances.
Good for: Trees, vines.
Key vars: axiom/rules, iterations, segment scale, axis mapping.
Global: axis, scaleMin/max, spanMin/max, stepMin/max, randomSeed.
Use the format Structure{n}{Type}{Axis}. Align axes with rotations and normalized iterators. Extend the generator with Spiral, RingStack, and RadialGrid for richer outputs.