7 Days

Last Monday I decided I would work on a different coding-related skill each day, for a week. These days I’m familiar enough with my own brain to know that swapping subject areas and deep-diving into topics suit my attentional style. Because motivation can be hard to come by when jobhunting and self-studying during pandemic restrictions, I thought I’d stimulate myself with novelty. It might even help me get psyched up to work on longer-term ambitions, like releasing my ritual Android app Candle Shrine, and also making a portfolio website.

Day 1 – C

On Monday I worked on C programming – an area I haven’t touched since 1999, ha! Yes as a kid I did a summer course which touched on some C. Anyhow, the aim was to set up the compiler and get console input and output. I used a build of Tiny C Compiler nabbed from the Tiny C Games bundle. My project is a simulation of life as experienced by our family cat, Goldie. Actually I’m pretty pleased with this, my sister played it through and enjoyed it. I was inspired by Robert Yang’s concept of “local level design“- a design aesthetic celebrating small-scale social meanings rather than top-down formalism. (This suited me because I don’t yet know enough C to write anything other than this ladder of if statements. Still, it works!)

Day 2 – Linux

The next mini-project was Linux shell commands. I used VirtualBox to dip my toes in -it lets you run any distro on emulated hardware, from a Windows desktop. It nearly locked up on my a couple of times, but in fairness my computer was running two OSes at once so I forgave it. It never fully crashed.

I’d hoped to get into shell scripting, which is the power user technique of saving listings of shell commands (a shell being a console for directly running programs or OS utilities, etc. – like the ol’ Command Prompt in Windows) as text files to be invoked as, effectively, little programs.

But all I had time for was to learn about 20 standard shell commands. However, I really liked this stuff. I can see why there’s a stereotype that devs use Linux. It’s rather satisfying to install stuff, edit files, and set up the file system via typed commands and not all that intimidating either.

Day 3 – Pink Sparks

See it in action here

This one was fun. I made a 3D particle demo – a spinning cube made of flying pink sparks. My focus here was to prove I could make a simple particle system, which indeed wasn’t hard, cribbing off Jonas Wagner’s Chaotic Particles and leveraging the extremely handy Canvas feature in HTML5. I also wanted to do 3D perspective, which was hard. However here I used the simplest possible version, a bare z-divide where x and y coordinates are divided by distance from the viewer. The proper way to do this involves matrices and transforms, but I’m not there yet.

If I get back to this the two things I’ll do are change it to defining line-shaped sources of sparks rather than point-shaped, and make some nicer data than a cube, like say a chunky letter ‘K’. This wouldn’t be particularly hard. Making a display of my initial fits with my interest in what I call ceremonial coding which I believe will be an emerging cultural field in years to come. As life goes online, we’re already finding the need to program and design software for celebrations and community rituals – an example being my graduation from my computer science course, which is being held on Zoom. I am certain that techniques from game design and aesthetics from digital culture will be important to create spiritual meanings and affirmations of identity on computers. My upcoming ritual app for Android phones expresses this conviction.

Again, Robert Yang’s post is very close to the spirit of this: “What if we made small levels or games as gifts, as tokens, as mementos?”

Day 4 – Huffman Coding

I hit a roadblock on Thursday. Huffman coding compresses text, by taking advantage of the fact that certain symbols (for example, ‘z’) occur far less often than others. To make a Java app implementing this was a meaty challenge, requiring binary buffer manipulations, a binary tree, sorting and file I/O. Still should have been achievable – but I let myself down by not rigorously figuring out the data representations at the start. This meant I threw away work, for example figuring out how to flatten the tree into an array and save that to disk, only to twig that the naive representation I’d used created a file far bigger than the original text file.

Though I was working from a textbook with an understandable description of the Huffman coding technique, that was nowhere near enough. I still needed to design my program and I failed to.

So I ran out of motivation as poor design decisions kept bubbling up. This was a stinger and a reminder that no project is too small to require the pencil-and-paper stage. On the plus side, I did implement a tree with saving and loading to disk, plus text analysis.

Hopefully I can reuse these if I come back to this. It’s a fun challenge, particularly the raw binary stuff and the tree flattening (although I don’t know yet if I want to store the tree in my compressed file, I think probably just the symbol table needed to restore the original.)

Day 5 – WebGL Black Triangle

In the spirit of Jay Barnson’s Black Triangles – though I’m sure it’s a million times easier these days!

Now this was pure fun. I used a tutorial to learn how to display graphics on a webpage using WebGL. I… frankly love the feel of OpenGL Shader Language. The idea of using a harshly constrained programming language to express some low-level color or geometry calculations, which is then compiled and run on your graphics card so you can feed it astronomical amounts of data for ultra-fast processing, is so satisfying. (Actually, especially the compilation process, and the narkiness of the parser where for example 1 is different to 1.0… it feels like you’ve loaded a weapon when you’ve successfully compiled at last.) I love graphical magic, but previously have been doing it at several removes, using wrappers on wrappers like Processing. I will definitely be doing more of this.

Day 6 – RESTful API

Another failure! I wanted to make a RESTful API demo as a bullet point on my CV, and host it for free on Heroku. But although I did some good revision on API design, when I got into implementation I totally got tangled up in trying to get libraries to work. Blehh!

I wanted my system to be standards-compliant so I tried using libraries that’d let me use JSON:API instead of raw JSON, which some people say is not good for APIs as it has no standard way to include hyperlinks which are, in fairness, central to the concept of REST (i.e. that instead of the client knowing to use certain hardcoded URLs, each response from the API includes fresh hyperlinks that the client can choose to follow).

But I got stuck when the examples for the library I chose wouldn’t compile because they required a new version of a build tool, Gradle, and despite trying some things off forums my IDE failed repeatedly to automatically install this.

They don’t call it “dependency heaven“!

If I get back to this I’ll use the build tooling I had working already for school projects. Life’s too short!

I wonder if the area of web services – so essential, stolid, bland – might be a natural home for rather pedantic personalities. The type who would make a typology of all things and publish it as a web standard. In any case, wading through some comments and blog posts and Wikipedia pages gave me a stronger understanding of state in web services than I had before.

Day 7 – Pathfinding in JS

Like the previous one, this project spun off into piles of research. But it’s all valuable stuff, I revised a lot of CSS and particularly the grid system, and got deep into JavaScript using this quite good book.

My plan was to implement a classic pathfinding algorithm, Dijkstra’s algorithm. But I wanted to have it so a little monster would chase your cursor around elements on a webpage! Well, as usual, I should’ve thought this through more. The fact is, web page elements are not intended to be processed as 2D shapes. HTML is semantic – web content is structured and manipulated as elements like paragraphs, headings, links that have meaningful relationships in the context of the document itself – with the final presentation of these elements done on the fly according to the user’s needs.

Anyway… my point is, I had to compromise to get this going. My original vision was of words arrayed around the page randomly, at different sizes, with a monster sprite threading his way around them.

My solution doesn’t have the words, just boring blocks, and though I think I could do words at a fixed size, having splashy words in different size could be quite a hassle.

As you can see, the paths go through diagonal choke points, something to fix

Nor did I get around to the monster although I have the sprite for when I do:

Heheheheheh.

But the thing that worked well for this mini-project was: web standards! In particular, I made the excellent decision not to hack CSS positioning from JS, but instead take the time to revise the CSS Grid system. Which, as you might imagine from the name, was actually perfect for this use case. Those numbered cells above are arranged by Grid.

Conclusion

That was fun. I might even do it again!

Side Project Satisfaction

Today I finished up a coding project, which was to make a simple synthesiser written in Java. I noted though, as I dashed off a quick readme file and uploaded the repository for the last time, a distinct sense of anticlimax, even disappointment. The app didn’t work out that well. Instead of writing an account of what I was trying to make and how I set about it, then, this evening I want to reflect on ways to avoid that letdown, specifically with side projects where you have total creative freedom.

This is about accepting and optimising for the way my brain works. Which is: it creates lots and lots of ideas at the start of a creative process. Here are some of the ideas I had for my synth:

  • adding harmonics by wave-folding
  • only using fixed-point arithmetic (inspired by early trackers and my general interest in retrocomputing)
  • using fast sine approximations
  • using sine lookup tables
  • stretched harmonics
  • harmonics detuned to simulate string mass
  • using Bezier curves as volume envelopes
  • doing additive synthesis by mixing together multiple instances of my basic instrument
  • doing additive synthesis by creating custom waveforms containing the desired harmonics
  • generating just intonated and 5-limit tunings
  • generating tunings from two overlapped harmonic series
  • generating 12-tone equal temperament and quarter-tone (24-tone) tunings mathematically
  • using the stuttering/echoing sound of buffer underruns as a musical effect
  • adding frequency modulation synthesis
  • having the synth be about a limited subset of sounds like bells, marimbas and bass
  • avoiding certain assumptions from the MIDI standard, e.g. removing note duration in favour of focusing on note onsets only (an idea influenced by my study of African-derived musics which have this emphasis)
  • using the synth in some kind of persistent, low-key online game as a way for players to leave melodies for each other to find
  • using rules to generate different melodies from the same basic info (say an array of integers), for example with different tunings or in different modes and scales
  • generating scales, chords and perhaps melodic cells or fragments geometrically, using relations I know from my study of music theory back in the day (e.g. a chord is every odd member of a scale is an approximation to 7 stacked fifths in a chromatic space generated using the twelfth root of two)
  • making an interface to expose these options interactively

And so on. The obvious common factor among all of these, I would say, is that there is no common factor. They are an extremely heterogenous bunch suggesting a whole lot of varied perspectives. Some are from a coder’s perspective (fixed-point calculation), some are about synthesising technique, some reflect my own limitations of ability, some are more like observations about the nature of music. Many have a distinctly contrarian flavour.

You can probably see the problem. There is no way to ever succeed at a project “defined by” such a list. And I’m not talking about success defined externally, but even just personal satisfaction. There are far too many requirements, many of which are contradictory.

The ideas there which are more rooted and achievable have another issue: they are technical challenges only, which makes them arbitrary. There’s no way to know if the solution arrived at is good, because there’s no agreed-upon way to measure performance. Should my bezier curve envelope allow two values for a given x input (which an unconstrained quadratic bezier can easily have), or forbid such curves? There’s no right answer because I haven’t defined what I’m trying to do.

This is in stark contrast to the school projects I’ve done for my higher diploma course: making a banking app, or an e-commerce website. Even if the work could get boring with those, the remit is clear and it’s satisfying when such a system comes together.

How did I manage to put a few weeks into my synth without realising that I hadn’t fixed upon a goal?

Or do I even need a goal? There’s nothing wrong with just fiddling about with stuff for fun, there’s even a fancy phrase to make it sound more official: “stochastic tinkering“. However, I know that I get my fun as a programmer in quite a specific way – by turning stuff that doesn’t work into stuff that does. When definitions are too loose, there’s no way to decide whether something works.

I’ve come up with a few pointers on how I might avoid this looseness in future.

The first is to design something conventional with a fictional, “normal” user in mind. This was how my school projects got done. This is good because convention (shopping carts in an e-commerce site, account selection in a banking site) guides you. This leverages the part of my mind that can’t stand to be wrong, and that likes tidying up: as long as the project fails to meet conventional expectations, I’ll be nettled into improving it.

However, finding the motivation to develop without the ego boost of originality would be hard for me. I know from the experience of finishing up my synth that work done just for the sake of appearing competent to strangers who come across my Github profile, isn’t very sustaining. The school projects had the virtue of being compulsory.

The second solution is to design something I’d like to use. This is… hard actually. It requires some self-awareness and honesty. I made a synth because I thought it’d be cool… or so I thought. Yet if I truly believed synths are cool, I’d probably have used one in the last few months; I haven’t done any synth-based music-making though in that time (despite having dozens of software synths installed on my computer). My conclusion is that I find synths to be a pleasantly intricate subject for mental distraction, but that I don’t actually have much desire to use them.

And similarly with the pixel art app I made before the synth. I like thinking about pixel patterns and generating them, yet if I liked making pixel art I’d be making some.

So, thinking honestly about one’s interests and requirements isn’t all that easy.

A third approach is to make something new, but very small. This worked well with something I made last year, an interactive sine wave visualiser. I actually made use of it, just for a second, while working on my synth to help me think about differentiating sines.

I’ve read advice to programmers about making tools that do one thing very well, and I can see the sense of it.

A fourth thing that has worked well for me is collaborating. When I’m working closely with others, my desire to appear right is a strong motivator. The hard part though for a side project is putting the energy into finding collaborators and the contradictory twin fears of not being good enough versus working with someone I feel is holding me back.

Those are actually familiar negative thoughts from my musician days.

Well, that’s what I wanted to write. Conclusion: even though my brain likes nothing better than lashing out idea after idea, finding the right one takes courage and deliberation. And it seems likely that good project ideas will combine a couple of the following: doing one thing only; being conventional; solving a real problem I have; being collaborations.