Postmortem for my First App

Three and a half months ago I started a software development course, to build a new career as a programmer. I’ve also quit playing music. As we come to the start of a new year I’m very happy with these choices and with the prospects ahead.

One of the things I’ve loved for a long time about programming was the culture of sharing knowledge. It directly influenced the tone of this blog. So, while I don’t know whether I’ll continue writing about programming on Drum Chant or make a new blog for it, today I want to try my hand here anyway at a software postmortem.

Following the time-honoured format (which I first saw on gamasutra.org I think, and also used on this blog before), I’ll introduce my project, discuss what went right in the production, what went wrong, and what lessons can be learned about software development.

Introduction

I developed my first app in Java this month. It’s a number-guessing game simulating a lottery draw. I call it Gambler’s Delight. I had previously worked on a similar brief for a group project in school which I enjoyed enormously. So I decided to remake that idea on my own, using a more elegant, manageable design.

The game affords multiple rounds of attempts to win the lottery. In each round the user fills out a lottery ticket of 1-3 lines, where each line is a guess at the 6 random lottery numbers which will be drawn. When the user decides to play their ticket, the application draws the 6 random numbers and tells the player how good their guesses were, awarding fictional cash prizes depending on performance. Finally, the app keeps a record of all the rounds played and displays this when the user requests to end the play session.

So, it’s rather like the Irish National Lottery‘s digital play platform. I didn’t refer to this when designing my game, but my effort converges on the same concepts.

How the pros did it

You may be already seeing some of the design issues I faced:

  • how to make sure the player chooses six unique numbers
  • how to have automatically chosen (“quick pick”) numbers
  • given that some lines are active and ready to play, some not, how to deal with the transitions from inactive to active and back

My own learning goals for the project were to get my head around Java’s Swing library, which provides platform-independent graphical user interface (GUI) widgets, as well as some intermediate programming concepts like interfaces, events, exceptions, and of course the object-oriented programming principles of encapsulation, inheritance and abstraction. (The fourth technique always mentioned with that group, polymorphism, didn’t really come into my app.)

Or, to put it crudely, I wanted to make a simple game but:

  • split it out intelligibly into classes representing real-world objects,
  • use the premade Swing classes more or less as they’re meant to be used, and
  • keep a handle on the structure and proliferation of my code.

What Went Right

A clean GUI: I designed the look of my program in one blast of inspiration, which luckily was then realisable in one of Swing’s layout manager classes, the euphoniously named GridBagLayout.

I decided that each line of 6 numbers would be built as 6 text fields, similar to a licence key or credit card number entry form. And I was able to have all necessary user actions available on this one, small window, in a layout based on the number 3.

The concept ((also demonstrating the importance of having appropriate stationery on hand 🙂 )
My GUI in action

Encapsulation: as you can see in the source code, I split the functionality of my game into 9 classes and and an interface. Many of these are satisfactorily neat and conceptually self-contained. Even the bigger ones use some basic principles to hide their data, i.e. private variables. Also, I followed the correct convention for passing arrays – copying their contents into a new array before passing that – to avoid giving the requesting class access to a private array in cases where this matters, e.g. the LottoTicket’s getResults() method.

Keeping control of my code: I was pleased that by the end of this project, I still knew clearly what everything did and where to look for any particular functionality. I could skim my code and know what I was looking at thanks to nice variable and method names, whitespace and my reasonably clear class structure. I’m an ultra verbal thinker so writing lines like “history.updateWith(ticket.getResults());” that do what they sound like they do in approximately readable English, pleases me no end.

Use of Java classes: the built-in classes I used – probably around 12 or so – were rewarding to study and build around. Of course they are, they’re made by top people! The experience of using things like Swing’s InputVerifier or Container classes, say, is of initial simplicity giving way to great depth and flexibility. The big but logical inheritance hierarchies of these components are inspiring. I’d love to make something someday as worked-out and usable as these. The only downside of my plug-and-play approach is that I ended up using a good few classes quite superficially. I can see how later it’d be all about digging down deeper and overriding parts of fundamental classes to put my desired custom behaviours in more unified containers that match their purpose more elegantly.

Use of events: I used a good few of Java’s event types and wrote one of my own, so now I have at least some insight into event-driven programming.

Bullet-proof UX and validation: I’m proud of this achievement even though conceptually, behind the scenes, it could’ve been cleaner. My interface instantaneously reacts to invalid input with an appropriate error message and an updated count of how many lines are ready to be played. The only exception is, I allow the user to leave fields blank for smoother navigation. It’s impossible to leave an unplayable input in a field, and impossible to play a line that doesn’t validate correctly (e.g. has blanks). There are two subtleties to this. First, I had to use multiple kinds of events to make sure and cover all interactions: DocumentEvents, FocusEvents, ActionEvents… and then pass the appropriate EventListener classes back and forth when building all the objects (lines, fields, verifiers) in my game. That’s overly complex for sure. On the plus side, I had to take care of weird player behaviour like going back and deleting numbers from previously finished lines. That involves some slightly tedious code but the result is robust.

Minimising hardcoding: I kept crucial gameplay variables in a separate LottoRules class and made sure that they only need to be changed once to correctly change the game’s behaviour. However, I chickened out of following this to its proper conclusion of allowing customisable line lengths and number of lines per ticket – the game logic can handle this, but the user interface wouldn’t dynamically adjust.

What Went Wrong

Having no target audience: the game was inspired by a brief for a college project. It doesn’t fulfill any real user’s needs and therefore there’s no point continuing to develop it. Honing in on excellent design becomes arbitrary in this situation. For my next project I’ll come up with something that I, and hopefully many people, definitely want.

Insufficient use of exceptions and defensive programming tactics: changes in one part of the code could easily cause crashes or undetermined behaviour because I don’t check the validity of values or handle wrong values (apart from the user input discussed above). That said, I think I’m right to move on without polishing this more.

Hardcoding: this point also contravenes good programming practice. The UI I made isn’t adaptable to different line lengths/amounts, and has some per-pixel hardcoding. But here I was coming up against the fact that system-independent GUI design is hard. Java’s Swing layout managers are pretty flexible and wide-ranging, but with that comes a lack of predictability and precision. I think next time I might try a different GUI technology – AWT, or something web-based – just to keep learning new stuff.

Lack of reusability: although I made one class explicitly for future use, (TextNiceties which deals with plurals and counting words) I mostly failed at designing for reuse which is, so my software engineering teacher says, the holy grail. Partly this is due to the trivial but finicky task: much of what I wrote is for the necessities of this particular game. Then there was the spreading of GUI code throughout my classes, which I’ll discuss below, but which obviously makes my code specific to one task.

Refactoring is hard: “restructuring existing computer code—changing the factoring—without changing its external behavior” as Wikipedia defines it, was challenging. I already had a working prototype at the start of this project, from my school group work. Unfortunately I tended to unthinkingly take elements of the previous design into my new one. And I also assumed that problems were already solved without noticing that with changed design assumptions, my previous techniques were now invalid. So, I made two failed attempts at restructuring my GUI code before settling on a pattern of passing a window (JFrame) object into my various classes so they could paint themselves onto it.

Deciding what object should have what responsibilities: I had the concept of an overarching “app” creating a lotto “ticket” containing “lines” which each contained number “fields”. Reasonable enough, but the question of which object should know about which other objects was hard! This applied to the UI creation, the validation, and the game state changes… I have tons to learn here.

Over-engineered interface: I allowed the user to invalidate a completed line of numbers by clearing text fields. This adds nothing, it’s merely a standard text input convention. I think an excellent design would intentionally limit such possibilities in the interests of clarity and simplicity. I note that the Irish National Lottery interface:

  • uses a graphical grid of numbers that are either selected by a single left click, eliminating duplicates automatically
  • doesn’t allow deselection (deletion) of numbers, so lines are simply always valid once completed – and bright colours are used to indicate the change to valid
  • therefore never has e.g. the first line invalid while subsequent ones are playable, an edge case I had to write a fair bit of overly-involved code to deal with

Conclusion

I’ll stop there. That’s a lot of chat about a learning project, but hey I’m proud of it and I sank a few days into it. Nice one if you read through it all and perhaps I’ll be back soon with a cooler project. A friend of mine gave me the idea of doing something that queries a web API, and I also think I want to do something with non-trivial calculations (maybe some geometry/graphics) and file handling.

*EDIT* Oh, one last addition – I think I know now what the solution is for organising the line, field and ticket objects and their drawing code. Sticking closer to the paradigm from John P. Russell’s excellent beginners Java book, I would go back to having each major element subclass a Swing component such as a JPanel, and draw itself in its constructor. And, I would structure the lines like a group of radio buttons: first a LottoLine would be created, and it would be passed into the constructor of all its LottoFields.

Ah well, there’s always more improvements to make. Still happy to draw a line under this project, cause it works and the code is readable.

A Bass Practice Setup in Reaper

A satisfying practice session can involve many subtasks. I’ve been using the music production program, Reaper, to conveniently manage some of these. In this post I’ll go through my setup. It’s a work in progress. Eventually, I want to have a friendly and supportive digital environment for my creative mind, something to help sustain the musical work I’m doing and minimise clicking around on the computer.

My setup uses one free VST plugin, some drum samples I found for free, three plugins that came with Reaper, the webcam software that was bundled with my (Dell, Windows) laptop, and Reaper itself. An unlimited licence to Reaper costs €60 for personal or small business use, that’s the only thing I paid for. Here’s what it looks like in action:

It took me a while to figure out the arrangement of screen space, so I’ll go through it bit by bit. The aim was to minimise mouse clicks and maximise time with my hands on my bass. This setup is what I leave running as I play.

  1. These are the basic track controls for the recording of my bass. Sometimes I use monitoring i.e. listening to the bass sound as it comes out of Reaper through my speakers, rather than my bass amp – but usually not. Using monitoring would allow use of effects, but there’s still perceptible latency (in the low two digits milliseconds) which I don’t like. I record everything and throw it out after. I keep my amp plugged into my soundcard all the time. I suspect this habit of recording everything may have led to some recent slight corruption errors on my hard drive, because recording involves constant drive access and I left it running for a few hours at a time more than once, by accident. So I put a recording time limit of 45 minutes in my default project options.
  2. My teacher in Amsterdam years ago, David de Marez Oyens, recommended using the waveform of recorded bass as a visual aid to check one’s playing, but I only realised how powerful it is recently. Seeing the waveform instantly gives information on note length and attack, timing and perhaps most of all dynamics. The consistency of my playing has improved from routinely having the waveform on the screen.
  3. The webcam image of my lovely self provides a check on my posture and particularly hand position (especially fretting hand wrist angle and finger curvature). As I’ve had health issues in the past from bad technique, this is a bit of a godsend.
  4. Reaper has a handy tap tempo function so I can click here to change the project tempo (i.e. if I want a slightly different metronome tempo).
  5. Assuming I pressed record at the start, this shows how long my practice session has lasted.
  6. Transport controls to start and stop recording, say if I’m listening back to myself or whatever. Eh, my point is that I don’t allow any of the other windows to cover this up.
  7. This is a cool little thing I discovered recently. You can “expose parameters”, or as I like to say “expose the knobs”, which means putting in a little dial in the track control which will control a parameter in one of the track’s FX plugins. In this case, this little dial controls what pattern my drum sequencer is on – here 0, which is an empty pattern and so plays nothing. But I can load up the sequencer with various patterns like a dance beat, claves, hip hop beat or whatever, and choose between them with this knob, without having to keep the sequencer window open.
  8. Track controls for the drums and metronome, if I need to adjust levels or whatever.
  9. I have lost probably about ten electronic tuners in my life. I just leave them behind routinely at gigs. So a digital solution is nice to have. Reaper’s standard “ReaTune” plugin works grand for bass once you turn up the window size to 100 milliseconds to allow for those big fat bass wavelengths.
  10. For drums and click I use the bundled plugin “JS: MIDI Sequencer Megababy” which is a nice piece of software. It takes a bit of learning as it uses a lot of keyboard shortcuts and some of its design choices aren’t immediately evident, but it’s great and minimises the clicks needed to input a rhythm (because you don‘t have to put in a new MIDI item). The controls could be easily used to manage polymetrically related click tempos (“okay put the metronome once every two and half bars of 4”).
  11. This purple horizontal bar is the click rhythm, in case I wanted to throw in a clave or something here. I could similarly display the current drum machine sequence, but it would take more screen space than this single bar, and also I don’t want my practising to be derailed by drum programming. For the same reason, I haven’t prioritised ease of adding or replacing drum samples – another rabbit hole.

To summarise, this setup lets me have the following functions available at all times as I play:
Tuner
Metronome
Drum machine with preset beats
Waveform visualisation
Video of myself

The plugins I use are:
JS: MIDI Sequencer Megababy (Cockos)
ReaTune (Cockos)
shortcircuit (Vember Audio) (a nice sampler)

Another function I haven’t tried yet would be putting in sound files to play along with (in full or looped). I used to use Audacity for this but it’d be easily done in Reaper.

The main downside from a user interface point of view is that each time after I change anything in Reaper or start recording, I have to click on the webcam software to open up that window again. Another thing is that changing tempo confuses things if done mid-recording and so necessitates a stop and a few clicks, although I could perhaps change some options to mitigate that.

Okay that’s it, I hope you enjoyed the tour. Feel free to comment about any software or configurations you use for practising!

A Composing Checklist

In my last post about my project to write a sketch a day, I talked about trying to compose purposely unfinished music, to stimulate players into completing it in performance using their improvisational spark and their knowledge of traditions such as jazz (or reggae, funk etc.). No sooner had I posted it than I figured out an obvious further thought:

That idea of provoking improvised reactions could be part of my composing practice. I could use my own music (or write new music, or use a piece from the repertoire) to stimulate further composing.

Absolutely nothing new in that idea as it stands – it’s called “development” or “contrafact”, or “sampling”. However, I realised that, in my practice, this process should take place using the exact dynamics I’ve been studying all along in this blog: the African and African Diaspora mode of improvised call and response within a groove. That is, the seed idea should groove and my spontaneous reactions should groove along with it. And there should be no limitation to the techniques or technology used – as long as there is this mutual grooving.

For example, I could:

  •  sample an old bass solo, loop the sample and improvise a bassline underneath
  • sequence a drum pattern and improvise chords on top
  • improvise a motivic solo over a standard, then take the best chorus as a melody and re-harmonise it
  • mash up a few cliched blues forms/song skeletons into a new form, then sing blues shapes over my form while playing it on bass to come up with a melody
  • dance to a dubstep mix and then subconsciously copy one of the drumlines (this wasn’t on purpose but it happened!)

The grooving stipulation directly combats my tendency to waste time idly fiddling with variations of a passage. Because now I’m forced to keep strict time as much as possible and also forced to make decisions in time (this is the essence of the jazz concept of “spontaneous composition”, I think).

By the way, such techniques as “jamming along to a recording of yourself” might seem trivial or even indulgent, but actually they bring new and worthwhile challenges. E.g. making a grooving and appealing-sounding recording of yourself!

There’s a subtle but very important function performed by all the examples above. I want to discuss it using a point of reference…. Seeing as my strategies are about finding inciting/provocative seed ideas and then reacting to them, the point of reference will be inciting/provocative gestures in groove music. Seeing as my seed ideas are meant to be beginnings for my creative process, I’ll look at beginning gestures.

Reggae drum intros are a great example of filling in to the top of the form; which is one of two basic options for kicking off a groove – the other being to just play a couple of rounds of the groove without the lead or without the full band. (More on that technique of layering here.) Fills are exciting, I feel, because they give a sense of an impending groove without revealing what it will consist of. Often, I’ve noticed they feature great timbre to convey an instant vibe – a notable feature of those reggae fills, but also found in blues, say:

I believe these gestures are comparable to hip hop snare drops, rap introduction cliches, and myriad rock’n’roll gimmicks. What do all of these do? They inject energy for sure, but also the set up the tempo, the feel (subdivision and microtiming), a vibe, the position of beat one and often a tonal centre!

My intuition is that seed ideas should contain all this info. To go even further, for my purposes (and in accordance with all of the traditions I’ve been talking about), the form is something that should be established in the seed idea – or at least, a clear tonal centre and length of cycle. The reason is that the type of interactive improvising – the “response” of call-and-response – that I’ve been discussing, happens when players can feel the underlying ground or form that they’re navigating.

Anyway, here’s a checklist for composing that I came up with two days ago:

  • Have a relaxed and open mind
  • Start with some technical practice on your instrument
  • All recordings must groove so use a metronome or just play with the fattest of feels
  • Try find a grooving coexistence of old (ground) and new (improv), e.g. improvise on a standard, sing over a bassline you wrote, interlock played improvisation with a tapped bell pattern, etc.
  • Look out for cool physical configurations i.e. unusual hand movements, combinations or instrumental approaches (for me this tends to emerge from technical practice which simultaneously warms up my hands, bores my brain and sharpens my awareness until I impatiently come up with something new)
  • Look out for cool timbre
  • Keep the harmony absolutely simple enough to navigate i.e. so you can visualise how melodic paths fit in the harmony in real time while devoting enough attention to treating them lyrically
  • Try ASAP to find the rhythmic cycle, top of form, feel and tonal centre
  • Feel how the harmony should move, and go with it if it turns out to be something familiar (I wrote an eight-bar section the other day without fully realising that it was “Donna Lee” chords)
  • Keep a notepad and recording tools immediately ready

It’s worked so far, although with the proviso that what comes out mightn’t be as hip as I’d wish for!!

I guess I’ll sign off here. I have more things to say but it’s best I write a few more tunes first. Thanks for reading! And please comment with your strategies for writing music.