Turtle graphics for the PicoCalc

There appears to be two implementation of turtle graphics for the PicoCalc, Pico Logo by @BlairLeduc and my own turtle module under zeptoforth.

For more information on Pico Logo, look at:

Pico Logo, of course, is a full implementation of the Logo language, of which turtle graphics is sadly but the most well-known feature. (Logo is really a classic Lisp minus all the parens.) I personally remember Logo from when I was in elementary school, but they never taught us about its features beyond turtle graphics. (Even then, I knew it was a better language than BASIC, though.)

The turtle module for zeptoforth, which can be seen at extra/rp_common/turtle_picocalc.fs, is another option. It is designed so its turtle graphics API is mostly compatible with that of Thurtle, a WAForth-based turtle graphics system that runs in the browser, and it has full access to the zeptoforth environment.

I am surprised that no one here has come out with a turtle graphics system for MMBasic, as that would be something that seems like it would be natural to implement. Is this perhaps due to the limitations of libraries under MMBasic, or is there not enough room to implement turtle graphics as part of MMBasic itself (cf. the thread here about MMBasic being ‘done’)?

Some key differences between the two is that Pico Logo, at least on the RP2350, uses floating-point, whereas the turtle module for zeptoforth’s API uses integers and it uses S31.32 fixed-point math internally. Other differences include that Pico Logo uses palette color with 256 colors selected from 65536 colors, whereas the turtle module for zeptoforth internally uses RGB332 color even though colors are selected as components of 0 to 255.

I am surprised more people have not tried out Pico Logo, especially since Logo is actually an all-around very nice language. You guys should try it out!

As for zeptoforth, it is not nearly as forgiving as Logo, e.g. if you recurse too deep you can cause undefined behavior or simply crash, requiring a reboot. Yet at the same time, if you want to use zeptoforth the turtle module provides easy means to draw graphics, and in most cases you can avoid writing code that uses words such as @ or ! which directly peek or poke memory.

Of course, I cannot help but give out some info on turtle graphics under zeptoforth, so here goes…

The API of the turtle module for zeptoforth consists of the following words:

setpencolor ( r g b -- )
setturtlecolor ( r g b -- )
forward ( pixels -- )
backward ( pixels -- )
left ( degrees -- )
right ( degrees -- )
penup ( -- )
pendown ( -- )
getpendown ( -- pendown? )
setxy ( x y -- )
getxy ( -- x y )
setheading ( degrees -- )
getheading ( -- degrees )
hideturtle ( -- )
showturtle ( -- )
getshowturtle ( -- showturtle? )
updateoff ( -- )
updateon ( -- )
getupdateon ( -- updateon? )
setpensize ( pixels -- )
getpensize ( -- pixels )
clear ( -- )
home ( -- )

These should be self-explanatory, especially if you have dealt with turtle graphics elsewhere.

Of course, this thread would not be complete without some screenshots, so here is one:

The code for this:

begin-module spin-square

  turtle import
  
  : draw-spin-square ( -- )
    page
    home
    clear
    penup
    1 forward 90 right 1 forward 90 right
    pendown
    200 2 ?do
      i forward
      89 right
    loop
  ;
  
end-module
1 Like

My BCPL OS fully supports Turtle graphics too. Here is your spinny square:

Code:

GET "libhdr"
GET "math"
GET "vdu"

LET d2r (d) = d #* M_DEG2R

AND spin () BE
{
  vduCls ()
  turtlePen (0)
  turtleMoveTo (160, 160)
  turtlePen (1)
  FOR i = 2 TO 200 DO
  {
    turtleMove (i)
    turtleTurn (d2r (89.0))
  }
}

AND start () = VALOF
{
  turtleInit ()
  turtleColour (colMustard)
  spin ()

  RESULTIS 0
}

-Gordon

1 Like

Thank you, @tabemann! That is a great comparison.

Logo needs a strong recursion capability since recursion as it is a well used technique in algorithms in the language. TCO (Tail-Call Optimization) allows for infinite recursion if your Logo procedure is implemented to harness it.

The examples above in Forth and BCPL can be writing in Logo as:

2 Likes

Are you not aware of the built-in turtle graphics in MMBasic? Here’s a summary of commands:

Appendix H – Turtle Graphics
Turtle Graphics
This release contains a very comprehensive turtle graphics implementation for all versions except the WebMite
RP2040 and WebMite RP2350.
The supported commands with “TURTLE “ prepended are:

Movement Commands
FORWARD distance (FD) - Move forward by distance pixels
BACK distance (BK) - Move backward by distance pixels
[TURN] LEFT [angle] (LT) - Turn left by angle degrees, 90 degrees if not specified
[TURN] RIGHT [angle] (RT) - Turn right by angle degrees, 90 degrees if not

Position Commands
SET XY x, y - Move to absolute position (x,y)
SET X x - Set X coordinate, keep Y
SET Y y - Set Y coordinate, keep X
SET HEADING angle (SETH) - Set absolute heading (0=up, 90=right)
HOME - Return to center (MM.HRES\2,MM.VRES\2) heading 0

Pen Control Commands
PEN UP (PU) - Lift pen (stop drawing)
PEN DOWN (PD) - Lower pen (start drawing)
PEN COLOUR color (PC) - Set pen color
PEN WIDTH width (PW) - Set pen line width

Arc and Curve Commands
ARC radius angle - Draw arc with given radius and angle
ARCLEFT radius,angle (ARCL) - Draw arc turning left
ARCRIGHT radius,angle (ARCR) - Draw arc turning right
BEZIER cp1 , cp1angle, cp2, cp2angle, end, endangle - Draw Bezier curve with control points

Basic Shape Commands
CIRCLE radius - Draw circle at current position
DOT size - Draw filled dot (default size=5)
FCIRCLE radius - Draw filled circle
FRECTANGLE width,height (FRECT) - Draw filled rectangle
WEDGE radius start end - Draw filled wedge/pie slice

Fill Commands
FILL COLOUR color (FC) - Set fill color and enable filling
FILL PATTERN pattern (FP) - Set fill pattern (0-31)
NO FILL - Disable filling
FILL - Flood fill at current position
BEGIN FILL (BF) - Start recording polygon for fill
END FILL (EF) - End recording and fill polygon

Cursor Commands
SHOW TURTLE (ST) - Show turtle cursor
HIDE TURTLE (HT) - Hide turtle cursor
CURSOR SIZE size (CS) - Set cursor size
CURSOR COLOUR color CC) - Set cursor color
STAMP - Draw a turtle at the current x,y position

State Management Commands
RESET [show] - clear screen and reset everything, show the turtle if show = 1
PUSH - Save current position and heading to stack
POP - Restore position and heading from stack
2 Likes

Sorry for forgetting about your turtle graphics implementation ─ and yes, now that I think of it, I have seen you post demos of it in action!

1 Like

Thanks for posting this! I must just never have noticed since while there have been many graphical demos for MMBasic posted here, I hadn’t recalled seeing any that actually used turtle graphics.

1 Like

So here is a Turtle challenge :wink:

A few years back, Randall Munroe of XKCD fame, posted a lovely piece of art with an obvious nod to Bob Ross

the original was in Logo, but the challenge here is to re-do it in language of your choice (Probably rules out Blair :wink:

I did it back then in my own RTB Basic dialect and used some automation which I wrote in Basic to do the conversion.

Enjoy :slight_smile:

-Gordon

I would implement that, but I’d first want an actual code listing in text of the Logo code being read off. Apparently the audio for that xkcd is more than 8 hours long, and I am not going to sit through it, nor does explainxkcd seem to provide a direct code listing that I could work off of.

here is a very simple MMBasic example of turtle graphics
’ Hilbert Curve for 320x240 displays
’ Based on original by “Sasquatch”

Dim cmap(15)=(RGB(black),RGB(blue),RGB(myrtle),RGB(cobalt),RGB(midgreen),RGB(cerulean),RGB(green),RGB(cyan),RGB(red),RGB(magenta),RGB(rust),RGB(fuchsia),RGB(brown),RGB(lilac),RGB(yellow),RGB(white))
Dim k$
C = 1

'--------------------------
’ Pattern 1
'--------------------------

Turtle RESET
Text 0,0,“Hilbert Curve (1 of 2)”,“”,2
Text 2,16,“Press Q to Quit, any other key for next”,"
",1

Turtle PEN UP
Turtle MOVE 10,210
Turtle PEN DOWN

HILBERT(5,90,6)

Text 0,0,“Hilbert Curve (1 of 2)”,“”,2
Text 2,16,“Press Q to Quit, any other key for next”,"
",1

If k$=“” Then k$=we.wait_for_key$()
If we.is_quit_key%(k$) Then End

k$=“”
we.clear_keyboard_buffer()

'--------------------------
’ Pattern 2
'--------------------------

Turtle RESET
Text 0,0,“Hilbert Curve (2 of 2)”,“”,2
Text 2,16,“Press Q to Quit”,“”,1

Turtle PEN UP
Turtle MOVE 90,220
Turtle PEN DOWN

HILBERT(6,90,2)

If Not we.is_quit_key%(k$) Then we.wait_for_quit()

End

Sub HILBERT(Level,Angle,Length)

If k$=“” Then k$=Inkey$
If k$<>“” Then Exit Sub

If Level=0 Then Exit Sub

C=C+0.1
Turtle PEN COLOUR cMap(C Mod 14 +1)

TurnTurtle(Angle)
HILBERT(Level-1,-Angle,Length)

Turtle FORWARD Length
TurnTurtle(-Angle)
HILBERT(Level-1,Angle,Length)

Turtle FORWARD Length
HILBERT(Level-1,Angle,Length)

TurnTurtle(-Angle)
Turtle FORWARD Length
HILBERT(Level-1,-Angle,Length)

TurnTurtle(Angle)

End Sub

Sub TurnTurtle(Angle)

If Angle>0 Then
Turtle TURN RIGHT Angle
ElseIf Angle<0 Then
Turtle TURN LEFT Abs(Angle)
EndIf

End Sub

Sub we.clear_keyboard_buffer()
Do While Inkey$<>“”
Loop
End Sub

Function we.is_quit_pressed%()
If Not we.quit% Then
we.quit%=we.is_quit_key%(Inkey$)
EndIf
we.is_quit_pressed%=we.quit%
End Function

Function we.is_quit_key%(k$)
we.is_quit_key%=UCASE$(k$)=“Q”
End Function

Function we.wait_for_key$()
Local k$
Do While k$=“”
k$=Inkey$
Pause 100
Loop
If we.is_quit_key%(k$) Then we.quit%=1
we.wait_for_key$=k$
End Function

Sub we.wait_for_quit()
Local k$
Do While Not we.quit%
k$=we.wait_for_key$()
Loop
End Sub

I ported your Hilbert curve implementation to zeptoforth at test/rp_common/picocalc_turtle_hilbert.fs.

Here is a screenshot:

And here is the source code:

\ Copyright (c) 2026 Travis Bemann
\ 
\ Permission is hereby granted, free of charge, to any person obtaining a copy
\ of this software and associated documentation files (the "Software"), to deal
\ in the Software without restriction, including without limitation the rights
\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\ copies of the Software, and to permit persons to whom the Software is
\ furnished to do so, subject to the following conditions:
\ 
\ The above copyright notice and this permission notice shall be included in
\ all copies or substantial portions of the Software.
\ 
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\ SOFTWARE.

begin-module hilbert

  turtle import

  create colors
  0 c, 0 c, 0 c,
  0 c, 0 c, 255 c,
  0 c, 64 c, 0 c,
  0 c, 64 c, 255 c,
  0 c, 128 c, 0 c,
  0 c, 128 c, 255 c,
  0 c, 255 c, 0 c,
  0 c, 255 c, 255 c,
  255 c, 0 c, 0 c,
  255 c, 0 c, 255 c,
  255 c, 64 c, 0 c,
  255 c, 64 c, 255 c,
  255 c, 128 c, 0 c,
  255 c, 128 c, 255 c,
  255 c, 255 c, 0 c,
  255 c, 255 c, 255 c,
  cell align,

  1,0 2value color

  : set-color { index -- }
    index 3 * to index
    colors index + c@ colors index 1+ + c@ colors index 2 + + c@ setpencolor
  ;

  defer hilbert-unit
  :noname { level angle length -- }
    key? if exit then
    level 0= if exit then
    0,1 color d+ to color
    color 14,0 fmod 1,0 d+ round-zero set-color
    angle right
    level 1- angle negate length hilbert-unit
    length forward
    angle left
    level 1- angle length hilbert-unit
    length forward
    level 1- angle length hilbert-unit
    angle left
    length forward
    level 1- angle negate length hilbert-unit
    angle right
  ; is hilbert-unit

  : setup-turtle ( x y -- ) page home clear penup setxy pendown ;
  
  : drop-keys ( -- ) begin key? while key drop repeat ;
  
  : draw-hilbert1 ( -- )
    -150 -50 setup-turtle
    5 90 6 hilbert-unit
    drop-keys
  ;
  
  : draw-hilbert2 ( -- )
    -70 -60 setup-turtle
    6 90 2 hilbert-unit
    drop-keys
  ;
  
end-module

Here’s the program in MMBasic:

TURTLE reset
TURTLE pen colour RGB(YELLOW)
TURTLE set xy 160, 160
FOR i = 2 TO 200
  TURTLE forward i
  TURTLE turn right 89
NEXT i

Here is a more elaborate space-filling curve than the Hilbert curve implemented with turtle graphics as an Lindenmayer system, specifically the Gosper curve.

The source code is at test/rp_common/picocalc_turtle_gosper.fs.

Here is a screenshot:

And here is the source code:

\ Copyright (c) 2026 Travis Bemann
\ 
\ Permission is hereby granted, free of charge, to any person obtaining a copy
\ of this software and associated documentation files (the "Software"), to deal
\ in the Software without restriction, including without limitation the rights
\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\ copies of the Software, and to permit persons to whom the Software is
\ furnished to do so, subject to the following conditions:
\ 
\ The above copyright notice and this permission notice shall be included in
\ all copies or substantial portions of the Software.
\ 
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\ SOFTWARE.

begin-module gosper

  turtle import
  
  : rgb { D: r D: g D: b -- r g b }
    r 255,0 f* round-zero g 255,0 f* round-zero b 255,0 f* round-zero
  ;
  
  : convert-color { D: f -- r g b }
    f 6,0 f* to f
    f 1,0 d< if 1,0 f 0,0 rgb exit then
    f 2,0 d< if 2,0 f d- 1,0 0,0 rgb exit then
    f 3,0 d< if 0,0 1,0 f 2,0 d- rgb exit then
    f 4,0 d< if 0,0 4,0 f d- 1,0 rgb exit then
    f 5,0 d< if f 4,0 d- 0,0 1,0 rgb exit then
    1,0 0,0 6,0 f d- rgb
  ;
  
  0,1 16,0 f/ 2constant color-incr
  
  defer gosper-unit-a
  defer gosper-unit-b
  
  :noname ( level length D: color -- D: color' )
    2swap { level length }
    key? if exit then
    level 0> if
      -1 +to level
      level length 2swap gosper-unit-a
      60 right
      level length 2swap gosper-unit-b
      120 right
      level length 2swap gosper-unit-b
      60 left
      level length 2swap gosper-unit-a
      120 left
      level length 2swap gosper-unit-a
      level length 2swap gosper-unit-a
      60 left
      level length 2swap gosper-unit-b
      60 right
    else
      2dup convert-color setpencolor color-incr d+ 1,0 fmod
      length forward
    then
  ; is gosper-unit-a
  
  :noname ( level length D: color -- D: color' )
    2swap { level length }
    key? if exit then
    level 0> if
      -1 +to level
      60 left
      level length 2swap gosper-unit-a
      60 right
      level length 2swap gosper-unit-b
      level length 2swap gosper-unit-b
      120 right
      level length 2swap gosper-unit-b
      60 right
      level length 2swap gosper-unit-a
      120 left
      level length 2swap gosper-unit-a
      60 left
      level length 2swap gosper-unit-b
    else
      2dup convert-color setpencolor color-incr d+ 1,0 fmod
      length forward
    then
  ; is gosper-unit-b
  
  : drop-keys ( -- ) begin key? while key drop repeat ;
  
  : draw-gosper ( -- )
    page home -64 32 setxy clear hideturtle
    4 3 0,0 gosper-unit-a 2drop
    showturtle
    drop-keys
  ;
  
end-module
1 Like

I know someone has done this before in the graphical demos thread, but as long as we’re doing Lindenmayer systems with turtle graphics I figured I’d do a colored Lévy C curve.

My source code is at test/rp_common/picocalc_turtle_levyc.fs.

Here is a screenshot:

And here is a source code listing:

\ Copyright (c) 2026 Travis Bemann
\ 
\ Permission is hereby granted, free of charge, to any person obtaining a copy
\ of this software and associated documentation files (the "Software"), to deal
\ in the Software without restriction, including without limitation the rights
\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\ copies of the Software, and to permit persons to whom the Software is
\ furnished to do so, subject to the following conditions:
\ 
\ The above copyright notice and this permission notice shall be included in
\ all copies or substantial portions of the Software.
\ 
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\ SOFTWARE.

begin-module levyc

  turtle import
  
  : rgb { D: r D: g D: b -- r g b }
    r 255,0 f* round-zero g 255,0 f* round-zero b 255,0 f* round-zero
  ;
  
  : convert-color { D: f -- r g b }
    f 6,0 f* to f
    f 1,0 d< if 1,0 f 0,0 rgb exit then
    f 2,0 d< if 2,0 f d- 1,0 0,0 rgb exit then
    f 3,0 d< if 0,0 1,0 f 2,0 d- rgb exit then
    f 4,0 d< if 0,0 4,0 f d- 1,0 rgb exit then
    f 5,0 d< if f 4,0 d- 0,0 1,0 rgb exit then
    1,0 0,0 6,0 f d- rgb
  ;
  
  0,1 16,0 f/ 2constant color-incr
  
  0 value length
  0,0 2value color
    
  defer levyc-unit
  :noname { level -- }
    key? if exit then
    level 0> if
      -1 +to level
      45 right
      level levyc-unit
      90 left
      level levyc-unit
      45 right
    else
      color convert-color setpencolor color color-incr d+ 1,0 fmod to color
      length forward
    then
  ; is levyc-unit
  
  : drop-keys ( -- ) begin key? while key drop repeat ;
  
  : draw-levyc ( -- )
    page home 0 -60 setxy clear hideturtle
    2 to length
    0,0 to color
    12 levyc-unit
    showturtle
    drop-keys
  ;
  
end-module
3 Likes

I created another demo of a multicolored plant using turtle graphics under zeptoforth. It needs the latest version of extra/rp_common/turtle_picocalc.fs because it uses the new words turtle::fgetxy and turtle::fsetxy to exactly get and set the turtle position. One could consider it to be cheating because it saves and then later directly sets the turtle position and heading, mind you.

You can get the source code from test/rp_common/picocalc_turtle_plant.fs.

Here is a screenshot:

And here is a listing of the source code:

\ Copyright (c) 2026 Travis Bemann
\ 
\ Permission is hereby granted, free of charge, to any person obtaining a copy
\ of this software and associated documentation files (the "Software"), to deal
\ in the Software without restriction, including without limitation the rights
\ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\ copies of the Software, and to permit persons to whom the Software is
\ furnished to do so, subject to the following conditions:
\ 
\ The above copyright notice and this permission notice shall be included in
\ all copies or substantial portions of the Software.
\ 
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\ SOFTWARE.

begin-module plant

  turtle import
  
  : rgb { D: r D: g D: b -- r g b }
    r 255,0 f* round-zero g 255,0 f* round-zero b 255,0 f* round-zero
  ;
  
  : convert-color { D: f -- r g b }
    f 6,0 f* to f
    f 1,0 d< if 1,0 f 0,0 rgb exit then
    f 2,0 d< if 2,0 f d- 1,0 0,0 rgb exit then
    f 3,0 d< if 0,0 1,0 f 2,0 d- rgb exit then
    f 4,0 d< if 0,0 4,0 f d- 1,0 rgb exit then
    f 5,0 d< if f 4,0 d- 0,0 1,0 rgb exit then
    1,0 0,0 6,0 f d- rgb
  ;
  
  0,1 16,0 f/ 2constant color-incr
  
  0 value length
  0,0 2value color
  
  begin-structure frame-size
    2field: frame-x
    2field: frame-y
    field: frame-heading
  end-structure
  
  : push ( -- )
    here { frame }
    frame-size allot
    fgetxy frame frame-y 2! frame frame-x 2!
    getheading frame frame-heading !
  ;
  
  : pop ( -- )
    penup
    here frame-size - { frame }
    frame frame-x 2@ frame frame-y 2@ fsetxy
    frame frame-heading @ setheading
    [ frame-size negate ] literal allot
    pendown
  ;
  
  defer plant-x-unit
  defer plant-f-unit
  
  :noname { level -- }
    key? if exit then
    level 0> if
      -1 +to level
      level plant-f-unit
      25 left
      push
      push
      level plant-x-unit
      pop
      25 right
      level plant-x-unit
      pop
      25 right
      level plant-f-unit
      push
      25 right
      level plant-f-unit
      level plant-x-unit
      pop
      25 left
      level plant-x-unit
    then
  ; is plant-x-unit

  :noname { level -- }
    key? if exit then
    level 0> if
      -1 +to level
      level plant-f-unit
      level plant-f-unit
    else
      color convert-color setpencolor color color-incr d+ 1,0 fmod to color
      length forward
    then
  ; is plant-f-unit
  
  : drop-keys ( -- ) begin key? while key drop repeat ;
  
  : draw-plant ( -- )
    page home -130 -160 setxy 25 right clear hideturtle
    2 to length
    0,0 to color
    6 plant-x-unit
    showturtle
    drop-keys
  ;
  
end-module
1 Like

are these not that? 2601: Instructions/Audio Transcript - explain xkcd

I should have looked closer – when I saw ‘transcript’ I assumed it was just a raw transcript of what was being said, rather than actual code.