10PRINT inspired "Snowcrash" in Emacs
Updated Saturday, Apr 19, 2025

The sky above the port was the color of television, turned to a dead channel.
— Opening paragraph from William Gibson’s Neuromancer.
So I thought to myself, why not write a screensaver for Emacs? Enter
snowcrash.el
. It’s not on MELPA or anything, but it does live on GitHub
within my Emacs configuration repository.
M-x snowcrash RET
looks like this:
It’s fun to look at or leave running as a screensaver!
Background

Figure 1: TV Noise, a.k.a. Snowcrash. Public Domain
This is Snowcrash. The TV turns to random noise and if you have sound, the speakers produce a sharp hiss. Some people find it soothing. Some find it a bit much and upsetting.

Figure 2: Classic 10PRINT. scrus, CC-BY-SA-4.0
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
Now, This is 10PRINT. a simple toy program from Commodore 64 days (circa mid 80’s) that draws a textual labyrinthine pattern across the screen. Bonus, there’s a fun, free book about 10PRINT. Don’t miss out on the refreshing take of 10PRINT’s cultural impact.
The catch? Not everyone has a C64 emulator set up, however, probably everyone has Perl installed. Here is a 10PRINT version for Perl using ASCII characters:
Why? How?
Alright, with knowledge of 10print and snowcrash/TV noise, let’s talk more
about snowcrash.el
!
I wanted to see how difficult it might be to create a simple Snowcrash-y screensaver mode in Emacs. My initial attempt “snowcrash-ified” a normal buffer instead of creating a new major mode. This worked, but didn’t have an easy way to stop the timer (responsible for redrawing) on the buffer’s deletion. Plus, the modeline looked real confusing with the major mode indicated as “Fundamental mode” (the least specialized text editing mode).
Unlike “10print”, what I call “snowcrash” does not involve scrolling text.
Instead, snowcrash.el
rewrites the buffer every second. “10print” randomly
selects forward slash (/
) or backwards slash (\
) for each character;
snowcrash.el
randomly selects a standard space (ASCII 0x20) or full block
(Unicode 0x2588 █
), creating a satisfying noise effect like an old
television.
I discovered the full block character using Emacs’s Unicode search
functionality nestled within C-x 8 <RET>
(insert-char
). I typed *block
in the minibuffer then perused through the match candidates. To prove how easy
it is to enter unicode characters in Emacs, I’ll insert umbrella, brain,
snowman emojis real quick here in a couple seconds: ☂🧠☃. Viola!
Other Emacs screensavers
By the way there are other cool Emacs goodies that can serve as screensavers. Here’s a short list. It is not exhaustive.
- M-x dark-souls - spam “You died” in the buffer (MELPA)
- M-x gameoflife-animate - Conway’s game of life (MELPA)
- M-x fireplace - cozy fire vibes (MELPA)
Possible iterations
Here are some ideas for further improvement generated while writing this major mode. Sorted from fun to boring.
- Add color!
- Ensure the
snowcrash-mode
works correctly with multiplesnowcrash-mode
buffers. - Ensure
snowcrash-mode
removes the timer and hooks when the feature is unloaded or the in the case of the buffer’s major mode changing prior to deleting the buffer.
Elisp Footgun: (random)
vs (random LIMIT)
I’ll conclude this post with a elisp quirk—an elisp footgun. The Elisp
(random)
function has several distinct behaviors depending on how it’s
used. This makes for a funny API replete with oodles of legacy vibes.
(random)
returns an integer betweenmost-negative-fixnum
andmost-positive-fixnum
inclusive.(random 4)
returns a random integer from0
to3
inclusive (0
,1
,2
or3
).
So good so far. Function named random
generates random numbers.
(random t)
reinitializes the seed to a random value.(random "something")
reinitializes the seed derived from"something"
.
Yep, if you pass a STRING or t
to (random)
, the seed is changed. On the
other hand, if you pass nothing (nil
) or an INTEGER, (random)
selects a
random INTEGER. I’m sure there was well meaning intentions in overloading
(random)
’s behavior by dispatching on the argument’s type and value. It’s
confusing as hell.
Compare with Python’s random
module possessing a random.seed()
and a
random.randrange()
separating out the APIs for easy access.
API Design Matters!
And a final quote reminding us that careful API design matters!
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.