Posted November 21, 2025 by Itooh
#music #generative music
Last week I finished composing the entire soundtrack of Starseed Harmonies. And it was not a small task! Starseed Harmonies is a single explorable song made of several loops of different sizes that the player can toggle in a non-linear way. Composing that kind of musical space is as much a matter of music as of game-design. In total, there are 169 loops in the song, with lengths ranging from 1 bar to 16 bars (not counting a particularly long one that goes up to 32). The last game for which I had to create a similar soundscape, Echoes Traveler, had "only" 112 loops. Starseed Harmonies is thus the most ambitious musical work I've created!
Designing such a non-linear song presents some specific challenges. As a composer, you can't precisely control the progression like you would in a traditional score: it's the player who will decide how the song will evolve! And any route they decide to take must be interesting and pleasant to hear. I'll list here some of the difficulties I had during the writing and composition of this soundtrack. From design conundrum to some technical troubles.
Starseed Harmonies soundtrack is made of short loops. The game is a DJ set that gives to the player the ability to choose which sample to play. Sure, offering long loops would be fantastic. But the game needs a lot of loops to be interesting. It would just be a nightmare to make each of them have long and unique scores. Therefore, we have to make them repeat. It can depends on the section, but most loops' lengths range between 4 to 8 bars. On a 120 BPM rhythm, it isn't that long. The main risk is thus to have these loops feel repetitive.
Now, repetition is actually nice in a music! It's one of the fundamental that makes some grooves enjoyable: the listener is able to anticipate what's coming on the beat. A composer shouldn't be afraid to re-use a pattern, especially for drums and chords for example. But for some parts, too much repetition can make the song dull and predictable. This is mostly true for melodies: if a short jingle gets noticed, it can quickly become annoying. Several times I wrote a melody that sounded great, only to realize that after 3 or 4 iterations it lost all of its charm and sounded like a scratched disk.
One of the easiest solution can be to add variations. A 4 bars melody can be changed into a 8 one just by duplicating it and changing some of its notes. It works even better if it's the last ones! This is partly how good melodies work: they use recognizable motives, and explore them in different ways. But adding more and more variations isn't the only solution! Sometime a melody can work as a loop just by making a smooth transition between its end and beginning. It becomes continuous, without a clear beginning and end.
However I learned to be less afraid of repetition, and sometime embrace it. As stated, it works well for chords or drums. And there's an important element that must be taken into consideration: the player interacting with the song. They will constantly add and remove layers. So even if the loops individually are short and repetitive, the global song evolution won't be because the player will create its own progressions. Starseed Harmonies is after all an electro song: it uses short samples, but they are mixed in various ways.
I must confess a crime: I used a single file for the entire song. Because it's a single song, after all! My goal was to keep everything as cohesive as possible. One file means that I would use the same instruments, with the same volumes (spoiler: actually no), effects… It allowed me to quickly compare some sections, and even mix them to easily move a loop from one section to the other. That is… until a certain point.
The DAW I used for Starseed Harmony is Waveform. My file eventually became a bloated mess. Dozens of tracks, colors rendered pointless, constant scrolling vertically and horizontally… There was also the risk of breaking something if I inadvertently recorded on the wrong track, or selected the wrong plugin to edit! Needless to say, it was also taking some time to load on opening.
Would have do it differently today though? I'm not sure… Because in the end, I needed to keep all the instruments at my disposition. Not only to keep them consistent throughout the song, but also to be able to try them, listen to them, decide which one to use. I could quickly visualize which instruments are overused, which ones are not present enough, and balance the song globally. If I had chosen to make separate files for each section, I would still have needed to save the instruments' configurations somewhere. So in the end, it would only displace the mess. When dealing with a project of this size, complexity is unavoidable. Although I'm pretty sure a professional musician would have made a better work at organizing the tracks and plugins (but my expertise is in coding).
That being said, working on such a large file in a DAW wasn't without consequences…
Wafeform is a fantastic DAW for Linux. It has some caveats, but compared to other tools it's a very solid option. I really enjoy working with it!
One of its strength is that it allows to use many plugins, as long as they are compatible with the OS. And it's here that I faced some troubles. DAW plugins are weird. They are often opinionated in their UX, and each one comes with their restrictions and bugs. One of the plugin would sometime completely erase the configuration I carefully crafted for the instrument (making me paranoid and saving as frequently as I could). One would sometime stop working and requires to reload the preset. And some of them even repeatedly made Waveform crash! Was it because of the size of the project? I did not remember them being so capricious elsewhere. And by the time their crashing became really obnoxious, it was too late to find a replacement. The only solution was to disable them and silence their track… Until I wanted to write a new part with them, that is!
By the end I must admit I had some reluctance opening that project. It was slow, would crash 4 or 5 times before stabilizing, and occasionally would break somewhere… Even though I found pleasure in writing music, these frictions made part of the workflow kind of a chore. At least, I now know which plugins I should try to replace in the future.
I frequently work on music by iterating. I search for a nice chord progression, then I play them in an interesting groove. After that, I try to add perhaps a bass part, a melody, percussions… I experiment with various layers, trying to think of what could be a nice addition to the ensemble. And I stop once it sounds satisfying. It's a messy process, I still lack the skills to visualize an ensemble early and think of each instruments in the orchestra relatively to each other. But for my level of amateur musician, it's good enough!
However it doesn't apply very well to this kind of project. The song for Starseed Harmonies, as well as Echoes Traveler, has numeric constraints. For each section, it must provides at least 10 different layers for the player to interact with (it's actually way more if you count some secret tiles that the game-design requires as well). I can't just stop when it sounds good, I must write as many loops as the level needs! How do I prepare all these layers? How to I make them cohesive?
The answer is… to improvise. I start from the chord progression, then I randomly pick an instrument, and try to write something for it. If it sounds nice, I keep it. Then I pick another instrument, and start again. After a while, when there are several instruments ready, I try to activate only a random selection to write the others on top of them. For each part, I change the mix. The idea is to avoid working on a single "harmony": each combination must be interesting, and each instrument must add something new. The result is a bit chaotic. I don't know exactly in advance where the song is going. But I get a lot of pleasant surprises.
There are some caveats to this method. When adding a new instrument, it is always tempting to write its score as if it was playing solo. But not all instruments can take the lead! In fact, none of them should. If a part is too bloated, it doesn't sound well once it is mixed with the others. But at the same time, it should remain nice to listen even if it's accompanied by only a few instruments, or even alone. It's a tricky balance, that requires some trial and errors. This might be one of the reason most of the parts in this song were first live played: I worked on it kinda like a jam, where each player improvise its part.
Sometime when experimenting with loops, I would find interesting melodies, or occasion to write a long improvisation. Some other time a particular instrument would fit really well with two specific others. However, these additions, despite sounding good, wouldn't fit with the game's constraints. Any tile must be compatible with all the other. And when activated, it must gives a perceptible feedback. Also it can be cut by the player at any time! This means that I can't develop long melodies, I can't lower the volume for subtle parts, I can't alter the chord progression… The player interaction must be taken into consideration. It can be a difficult decision to put away some ideas because they're not compatible with the game-design, especially when you're on a creative mood. Sometime you must refrain yourself, and think more as a game-designer than a musician.
It can also be a matter of artistic choice! In the last update, I removed an instrument that was in one of the ending. It was really good sounding though, and I was extremely happy with the result. But there was one issue: that ending was supposed to convey a specific mood, and this instrument was driving the music away from it. Even if the part was beautiful, it was playing against the identity of the "scene". So after some hesitation, I replaced it with another that better convey the wanted atmosphere for that screen. It's not completely deleted though: I moved it away to another ending! So it's not lost, and some players will still experience it. Even if it created something really special initially, it's better for the game cohesiveness to have it this way.
This is another strong constraint that I already mentioned in a previous devlog. Starseed Harmony is made of 4 sections, between which the player can navigate at any time, and almost in any order. On top of that, there are several endings, each one with their own loops. How to ensure that the music keeps sounding cohesive when moving from a section to the other? The first solution I applied for this problem is to always wait for a pair of bar before moving to another section. This way I have a bit of control on when the change will be made. But it creates a strong composition constraint: every chord progression must take into account that it can switch to another one every two bars! Fortunately the song stays in D# Mixolydian, so a lot of chords are compatible with each other. There was no precise science for the composition: I tried different things, and hoped it work. Some transitions are better than other, sometime you can feel that a chord progression is abruptly cut, or that you arrive at the second half of a melody. But it's never dissonant.
There's also the matter of the present instruments. The player can move from an area where they have activated almost all the tiles to one where only two loops are playing. The difference is drastic! But there isn't any good solution for that. I considered writing transitions tracks with percussions that would play between areas to smooth the change, but it wasn't always conclusive, and so not worth the effort. I still kept that idea for endings though. Because there is a lot of chances that there will be more instruments playing on an ending than the area just before it. So each ending as its own transition that play on the 2 bars before it. It's not perfect, but it creates some anticipation.
But overall, I embraced the contrast there can be between sections. Sometime the song cuts abruptly to a quiet part, and sometime it suddenly gets a lot of energy. That just how it goes when the player is in control of the song. Even if there are cases where it seems odd, it can also create pleasant surprises!
The perpetual problem with generative music: how loud should each track be? Sure, if they're all playing together, I can adjust their volume to have a nice balance. But then when only some loops are playing, it doesn't work anymore! And remember: every single loop must be heard. Even if a dozen are already playing, if the player activates another one, they should ideally notice the difference. I say ideally, because at some point this is not really possible. High pitched instruments don't need too much volume to be heard, they easily stand out. It's bass and lower chords that are trickier to manage: they easily get masked by a crowd, but if they take too much space they create too much noise, especially if there are several of them! In the end it's another delicate balance to manage. Not impossible though, but it requires some trial and errors. I frequently changed the volume of a loop after realizing it was either unnoticeable or too present.
One solution that helps though is the use of a dynamic compressor. It's a node put at the end of the audio system that lowers the global volume if it gets above a certain threshold. This way the song can be loud enough when a few loops are activated, but automatically decreases its volume if there are a lot. Ensuring that the song stay within the same volume boundaries! However, I discovered that the compressor shouldn't have a too strong effect. At first I gave it a strong ratio and a large range, but it made the song… noisy and unpleasant? It's difficult to describe, but when the compressor is applied like that, it kinda "flattens" the result. Every sound gets mixed, there is no contrast anymore, and although the result sounds the same, it's exhausting to hear and even causes headaches.
So I kept the compressor, but made it very subtle. Too much of it is actually detrimental for the song. It's really just here as a security to prevent strong peaks.
Finally, there's the matter of all the files to manage. Each loop is exported as a .ogg file (I then use Orchestre-JS to play them in sync, but I've already talked about it enough). There is an option in Waveform to export each track separately. But as you saw above, I have loops scattered everywhere in the tracks, with different sizes, empty spots… And I also must take reverb into consideration: some loops needs a longer silence after them than other! Which means… Yup, I had to export the loops one by one. Which was actually not such a daunting task. I learned from mistakes I made in Echoes Traveler: this time, I didn't wait until the very end to export the files. I made exports frequently, and implemented them as soon as possible. I quickly adopted a workflow to optimize every step. Select the track, adjust the markers if needed, export in the target folder, write name, rince and repeat. There was some hiccups, but doing that for small chunk of progress made it not too laborious.
The implementation in the game required some organization as well. There's an enum in the code that lists every instrument's name. Every time I create new files (and am ready to use them), I need to add new values. Then for each loop I must specify a configuration: how many bars it takes, on which position in the grid it should be, how much it costs… Once again, this can't be automated, and must be written by hand. But again, with good organization, it can go fast. I initialize these configurations by copy-pasting existing ones. A lot of loops in a section share the same length, so I can set a default value to all of them and adjust the exceptions. I have written an utility algorithm that place tiles randomly, I can then adjust some positions manually in a CSV. As for the prices, it's a bit arbitrary: if I feel that this instrument should be "easy" to add, I set its cost to 1, 2 if it's a bit fancier, 3 for instruments that should be added at the very end. After that there are some values to add in some other files, make sure that the new files are registered at the right places, eventually configuring new areas with their colors and properties… It's tedious work, but fortunately the code is typed, so any omission is quickly detected. By this point I also have several commits where I added a new area, so I can refer to them to remember the steps needed.
Again, this is facilitated by the fact that I didn't implement everything all at once: adding each section of loops one by one makes this more manageable, and also more rewarding. Every time I finished to export and implement a part of the song, I could immediately play with it, and even publish it!
There might be a lesson that emerges from all these points: when creating a large music system, working with iterations is the right approach. My workflow for music creation is messy. Like many other creations, this song was build with lot of experimentation and fiddling. But I was able to obtain a rich and complex result by working on individual bits and adding them one by one, refining some of them as the project evolved. The result was unpredictable, as with many generative music. But it found its own consistency, and through a lot of compromises it manages to offer a variety of pleasant interactive experiences.
Starseed Harmonies is still in Beta. As of today, you can only hear about two third of the entire song. But each update will now add a new section, and I'm eager for you to hear them! Although I must warn: the last of them are really well hidden. But it's one of the beauties of interactive music: each experience will be unique to those who play it.