I'm Just an Average Magical Girl, Sorry. was osu! UCI's fall 2015 beatmap project. Our osu! map included an original background, storyboard, mania set, and two standard maps. The song was produced by MikitoP and sung by Sana.
osu! UCI by now just finished Sweet Regret, our summer beatmap project, and it was now the start of the fall quarter. The club overall had a really good start to the quarter, picking up a lot of new members. I was really excited to get to know everyone and work on projects with them.
Very early in the quarter I announced that we would work on a beatmap project. Royce and Justin on the officer team would be helping out. Beatmap projects were probably my favorite activity from osu! UCI. I loved working with others and developing things together, something I valued from my long time stay at the Video Game Development Club at UCI.
We didn't need to have a target number of people in mind for the project. The beauty of osu! beatmaps was that you could throw people in and out on a project very easily. Different from video games, you weren't bottlenecked if you didn't have an artist, programmer, or designer. Actually, designers were probably needed. You can't have an osu! beatmap without the map itself, or can you?
That being said though, I was a little bit disappointed in our turnout. I mean, from osu! UCI's side, we had a respectable number of people, but I also branched outwards to try and look for more interested members. That went pretty sour pretty fast. Namely, I went to the VGDC fall quarter pitches and pitched our beatmap project. To my surprise, I think only a single person signed up for our project.
I don't know what happened. I think I carried a lot of good leadership skills and experience behind my back, so I thought at least through my background I could get some people. My pitch speech was a little shaky, so maybe I didn't get everything I wanted across. Or maybe at the end of the day, no one wanted to work on a pretty obscure rhythm game where you didn't actually work on the fundamental game itself.
I don't know. I thought osu! beatmaps would fit developers well. Artists could make backgrounds or sprites. Designers could go wild making maps. Music producers could have their own music worked on and put in a game. Programmers had a lot of interesting opportunities with storyboard. All of this was also in a low pressure environment since parts could be added or removed relatively easily.
I guess people just wanted to work on more traditional games. It didn't seem like in general too many VGDC developers were interested in rhythm games. The signup turnout pointed to that. I was thinking about trying to get osu! UCI to pitch again, perhaps each quarter, but seeing how poor a fit osu! beatmaps were with VGDC, it probably isn't worth the club's effort.
The final team just consisted of about half a dozen members from osu! UCI. We spent the first week or two announcing the project, gathering signups, and planning for VGDC so it wasn't until around week 3 that we got to work. This wasn't exactly an early start, but I don't think the timing was too bad. 7 weeks was plenty enough to make a map and illustration.
Probably the only limiting factor with the time was that it would be difficult to produce original music for our map at that point. In our previous two projects, we had a music producer and friend of mine, Wes, who helped us out. How he worked with us was that he would give us a rough version of a song before spending a lot more time expanding on it. He needed some time, however, before he could give us a rough version, and we probably couldn't afford to wait around that long for this project.
I think it's worth asking why we didn't grab Wes again for this project. After all, we've been basically working with him for 4, 5 months already on Silicon Heart and Sweet Regret. If I had gotten contact with him earlier in the quarter and already asked him to help out, we could have worked with an original song.
Most of it I think was just that he's kind of a difficult person to contact. Before, I reached him time to time when I hung out in the VGDC club room a lot, but since I've been less active in VGDC and instead focusing my time on osu! UCI, I didn't visit the room much anymore.
For most of Sweet Regret, he was often hard to get in touch with. This could be blamed partly on summer, as we didn't see each other in person and he wasn't nearby. Whenever I needed him, I usually got a hold of him by calling him directly with varying degrees of success.
Towards the end of Sweet Regret, he gave us his final version of the song, and then we didn't really speak much. The next time I talked to him was when Aaron finished recording a playthrough of our map, and we gave the video to him to post up on his Youtube channel. That was pretty much all the conversations between us.
I don't think we parted on any bad terms after Sweet Regret finished. From his perspective and what he's alluded to me, I think working with us was a pretty unique experience from a music producer's standpoint. It's not often you get a crew of creative developers to help make artwork, animation, and maps for your song, all for the purpose of trying to put it into a game. He expressed some mild interest to possibly help out again in the future, but I never got back to him.
When Royce and I were planning the project early in the quarter, we of course talked about possibly getting back Wes. I think I was the one who suggested we could consider other options. It's not anything against him. He's probably the most talented music producer, or only music producer, I know and have worked with in person, but for various reasons, I wanted to try something new.
I mean, Wes wasn't a professional, so there's that. But inexperience was something I was fine with overlooking since I valued having an amateurish collaboration and original production. One thing he struggled with, however, was making fast songs. For Sweet Regret, we requested something ~180 BPM from him, and he made something at 180 BPM, but it felt a lot slower, like 90 BPM.
For an osu! mapper, high BPM songs feel better in the game. It's easier to make more difficult songs because you can put in more sensible notes, and it's also easier to make a wider variety of difficulties for a song. We had some problems mapping Silicon Heart, and Sweet Regret too, because of the slowness.
So because we hadn't heard word from him a for a while and in an effort to try something new, we decided for this project that we would pick the song ourselves. I'll say now, however, that after everything on this project was said and done, I prefer the old producing days when we had someone make a song for us.
It just feels... more appropriate for a club project when everything, especially the music, is done by scratch. At the core of a rhythm game is of course the music, and having original music to work with feels a lot more fun and exciting. I don't know. I can't really put it into words. A lot of people have their own personal preferences for songs and music. If they have a particular song they want to map, it's probably better in my mind to just map it by themselves.
That's one of the problems I was kind of hesitant to deal with when we were choosing a song for this project. I had some songs I really wanted to map or work on, but I was unsure how to handle bias in my or others' suggestions. Democratic voting was an option, but it seemed really forced and could upset some people in end. I think the best option was to just talk it out and try and reach some agreement.
The way we handled it seemed pretty alright in the end, but only because mostly everyone was pretty open-minded, or at least seemed that way. We ended up choosing one of my songs I proposed, and I hope everyone was okay with the decision. I don't know, maybe there're still people in the group with some regrets or grudges, but I our selection process was fairly thorough.
The way we decided was we first had a Google doc of suggestions. Royce and I put up the most, and I myself put up the largest majority. There were a few other suggestions here or there from other people, and we had a pretty big list in the end to choose from. I think going forwards in the future, if we do something like this again, we can just have a max limit of songs per person, and then narrow it down from there.
Once we had a big song list, mainly Royce and I got together and started cutting out choices. We removed songs that we didn't like or didn't feel like would fit osu! for some reason. Some were too slow or too weird or too annoying. Eventually, we got down to like maybe 3 or 4 that we both liked.
Then, we were kind of a little bit too touchy, and we didn't want to offend one another or appear too biased picking from the last bunch. I liked all the songs too for the most part, so working on one or the other wouldn't change too much. In the end, we got a third party vote from Justin who swooped in and picked this magical girl song out of the ones remaining, so we went with this.
I'm Just an Average Magical Girl, Sorry. was a super cute song by one of my favorite music producers of all time, MikitoP. I usually like the slow guitar ballads by him, but when this song came out I couldn't stop listening to it, and I really, really loved it. It's a kind of old song that I had forgotten about, but I stumbled across it again when looking for songs to propose.
I basically went through my entire MikitoP collection looking for songs that we could use. A lot of his songs were too slow or already mapped so I threw out a bunch of choices. This song was somewhat on the slower side, but it felt packed enough and was short enough. Also, as far as I knew, it wasn't mapped or touched before on osu!, so I could bank on some of its hipster value.
I knew Royce and some others would probably like it because it sounded pretty bright and upbeat. This wasn't really my preferred type of music, but I could see others liking things like this. Sana was also a very famous singer around osu! parts. Her HoneyWorks songs were really well known and well played.
And last but not least was the content. This song was part of a larger album about magical girls, a genre made famous and popular by Japanese anime. But it's not about the magical girls one may be familiar with. Instead, this album, Mahou Shoujo OverAge, focused on older, over age, washed up magical girls. It makes an interesting twist on the magical girl genre and looks at the unfortunate realities of being one.
I think my fellow coworkers on the project could appreciate this kind of odd humor. All of us were pretty much anime nerds familiar with magical girls, so it was interesting to see a song and album like this exist. The original on the album was sung by Hatsune Miku, but the Sana version was released online at the same time separately.
Before we go onto the specifics of the project, I guess it's worthwhile to note a funny event gathering the members together. This project is dubbed by me as Project Kenneth Legaspi because of our odd occurrences with Kenneth Legaspis. So, the first thing we thing we did on this project was get on Facebook and make a group page and group chat for us. I was kind of lazy and wanted Royce to take over more leadership, so I asked him to handle this and add everyone in.
Well, a very interesting thing occurred. Turns out he added in a Kenneth Legaspi, but it was the wrong one. But the even weirder thing was that we actually knew who this other one was. Alright, so first let's explain the one added in. What I imagine that happened was he looked up a Kenneth Legaspi, saw that he was part of an osu! group, and added the first one onto our page.
Turns out, however, this Kenneth Legaspi was from British Columbia, Canada and not Irvine, California. He was actually part of the osu! North America Facebook group, but not the osu! UCI group. The weird thing though was that we knew who he was. On osu! he was known as Dunois, and he played in our osu! UCI Summer League for a while before dropping out due to commitment issues.
I don't remember exactly what happened in the league, but from what I could recall, Victor made a mistake in dropping Kenneth out of the tournament before adding him back in later. But by then he was already missing a bunch of matches from our poor planning and his personal activities, so to not expedite his eventual loss, he decided to drop out.
Anyways, we didn't find out about the mistake until a while later, and I'm sure Kenneth was kind of confused. The real Kenneth Legaspi we were looking for actually did not go by Kenneth Legaspi, which is probably why we had this problem in the first place. In our club, he called himself and we called him Matt, but on Facebook he went by his middle name, Kenneth. What a coincidence and small world.
So now we have Matt Kenneth Legaspi, another Kenneth Legaspi, and to make things even more confusing we also had a completely separate Kenneth, Kenneth Yam, who goes by Kenny. We here at osu! UCI have a proud tradition of trolling and meming, so I too changed my Facebook name to join the party, and I became Max Kenneth Legaspi Chung for the next 60 days.
Kenneth, hereby the Canadian, said he would help out anyways as a mapper. He seemed okay with the song and just wanted to go with the flow I suppose. Unfortunately, he was pretty much a dead rock on the project. It was difficult to coordinate with him online, and after a while of not showing any work, we ended the quarter with nothing from him. Things happen. He was working remotely, so I can understand his lack of commitment. We still had other maps so it's not like anything important was hinging on him.
Alright, now I think it's time to dive into the project. The first thing I did was organize the art team to make the background. Seeing how time consuming the backgrounds for Silicon Heart and Sweet Regret were, I wanted to split up the work so that it wasn't shouldered on one person alone. We had several artists, so I wanted to put all of us to good use.
I probably could have executed everything myself if it came down to it, but when I told the others about a concept I wanted to do, Nina volunteered to do the sketch for us. This song captured the bad sides and difficulties of being a magical girl. My idea was that I wanted to draw a magical girl in one of these uncomfortable situations.
And what are magical girls probably well known for? Transformations. Every single anime of the genre has some ridiculous transforming sequence where girls change out of their normal school clothes to their battle attire. What if instead of having a cool sequence they had to change clothes themselves? That was what gave birth to this picture, where Miku awkwardly changes in a bathroom stall.
We used Miku because the original video featured her in a magical girl outfit. The outfit itself can be seen lying on the toilet in the picture. Nina immediately liked the idea and worked on a couple different sketches. Out of those, we chose the one that was what I most closely imagined. She made a few adjustments, and I would have liked for her to do more, but time was running out so we worked with what we got.
With the sketch done, the plan was to split up the rest of the work between myself and Matt. I wanted to do the lines since that my specialty and preference. Later, I would pass the line art to Matt to color. Matt was pretty inexperienced in digital art, so he could use this time to practice coloring before actually doing it.
The lines took a while for me. I took some generous liberties with Nina's work and redrew some parts as well. That being said, I don't think I fixed everything thoroughly enough. The biggest thing that annoys me now was that her neck still seems to be twisted too far and her face seems like it's too squished or something. I think I did the best to my abilities though. The end result was pretty close to what I pictured.
I then handed it off to Matt. For someone with not a lot of digital or art experience, I think he did alright. Improvement-wise, he could work on pushing darker values, fixing up blemishes, and making blending smoother. Some colors were kind of wonky too like the bright purple bag. I'm not a color expert, so I shouldn't say too much about it. I'm not going to complain too much since he put in a decent effort for the project.
He then passed it back to me, and I put on the final touches. Nothing big, these were just adding in the credits on the bottom right and resizing it to osu!'s resolution requirements. For this project we uploaded everything through my osu! account, osuuci dot com. My account was basically like the club's account, so having everything udner me made the most sense. We used to have a separate osu! account, osuUCI, before having it banned after realizing it broke multi-accounting rules.
After finishing the illustration, I was going to work on a storyboard right away, but a bunch of things got into my way. The biggest was managing the osu! UCI Fall LAN. This required a lot of my attention in prep work and website work, so I had less time to focus on this project. I didn't get a chance for the rest of the quarter to work on the storyboard, but it would later become my winter break project.
The storyboard wasn't really necessary for now though. If worst came to worst, we could have just scrapped it and not had one. What was important, however, were our maps, which had some varying degrees of progress so far. We organized our mappers by difficulty. Some chose to pair up with each other or work on different modes.
Kenny would take care of an easy/normal map. Don, who had very little experience with mapping, paired up with Justin to make a hard/insane map. Kenneth was going to do the hardest standard map for us, but as mentioned before, he dropped out of the project. And finally, Royce would make a mania set.
Kenny did good work. He had only a little bit of mapping experience in the past, but the maps he made previously had some grave errors like lack of distance snapping. To rectify his mistakes he wanted to work on something slow and simple, so he worked on an easy map for us. He worked pretty fast and probably could have made a second map for us, but with time trickling down, I felt it would be best if he just focused on a single map and polished it up.
Don was completely new to mapping, but he wanted to give it a shot. Under the guidance of Justin, who's had some experience, the two worked together in collaboration. They were kind of an odd couple. I don't think either of them worked on the map outside of club meetings, so their work was limited in that regard. They also did quite a bit of cheating in order to fill out the entire map.
Half the map, if I recall, was just composed of copy pasted parts from earlier. There were a lot of repetitive combos and sections. The biggest problem of all, however, was the timing. Their entire difficulty was mistimed. It could have a problem with mp3's, as Justin supposed, but they didn't bother to fix it, so we left it as is.
I think it's safe to say that Justin didn't do a great job leading the duo. Most of it I imagine was just his own commitment issues. At this point, he pretty much 100% stepped away from the game. The last time he played osu! seriously was months ago. He may have still been a little interested in the creative aspects of mapping, but as you can see, his effort and concentration wasn't here.
Royce was the last mapper. He too had kind of an interesting background. Over the last couple months he, like Justin, left the game in a way and stopped playing. In his case though, he only stopped playing standard and instead moved onto mania. I don't really know the exact reasons why. He started playing 4K mania and really enjoyed it, so most of his focus went there. I guess less than a reason for quitting standard was more of a reason for liking mania.
He still plays standard occasionally in lobbies with us, but this was quite irregular and only in small spurts. He's pretty vocal about all his play problems, in his inability to hold combo and getting triggered every minute or so, or maybe that's me. Normally, he plays mouse, but he did try tablet at one point. That went terribly somehow as he developed tendinitis or something likewise severe in his hand from having a bad grip. I think ever since then he may have been scarred, physically too, from playing standard.
As for maps, he made a full set for mania. I can't comment too much about mania since I don't play it, but I think Royce cut a few corners here too. From what I remember, he told me that one of the harder maps was just an easier map copied over and added to. I don't know if that's a common practice. I would assume not. His maps were also pretty difficult, at least for me. I could barely play the easiest one, and the next one up was too much for me.
By about week 9, most of everyone had their parts in. Our background was finished, and the first drafts of the maps were complete. That week we held a special meeting with the mappers to critique each others maps. This was something I wanted to do that was inspired by osu!'s beatmap modding practices. I think it's very valuable to give feedback to other mappers, and the best environment to do so would be in person.
Our meeting didn't quite go as good as it probably could have. Don and Justin's map had a lot of deep rooted problems like timing and repetition issues that we couldn't really say much on. Kenny's easy map on the other hand was pretty complete, so we offered some tidbits of advice to him. None of us were experienced mappers or played much easy maps, so I don't think our suggestions were very good, but regardless, I think it was a good experience to get some fresh eyes on a map.
The only other problem in the meeting was time. We held a relatively brief meeting which unfortunately pressured us to quickly speed through the maps. Next time I'd like to spend a lot more time and maybe more meetings checking up on people's work. Also, Royce didn't get feedback at all since none of us played mania. I asked him to maybe seek out Brad or Haoming for some help, but I don't know how that went.
By the end of the quarter, I bundled everything neatly online under my account, but it wasn't complete yet. I only half started on the storyboard at this point, and it wouldn't be until a little ways into the break that I finished everything completely. The storyboard was quite a bit more complicated than I expected since I wanted to do everything from scratch.
My biggest problem was probably using C++. I wanted to use this project as a chance to work in it again, but due to the nature of the language, things naturally got messier and more complex than at first glance. I made a storyboard library in C++ from scratch, following the similar format of the Python one I made for Sweet Regret. This involved handling sprites and printing their various transformations to a file in osu!'s specified format.
I had a particular idea in mind I wanted to explore for this storyboard. Since the song had vocals this time, I wanted to try making a lyric video and displaying each line of the song one by one in some glorified format. The idea I settled with is what you see now, where each line gets shown and then moved adjacent to the next line. This continues as more lines pop up, and all the previous lines move together.
I got some help from Royce to do some lyric work for me. This time, he didn't need to do any work from scratch since there were already some translations online. It took some work, however, to adapt the translations for use in my lyric video. The biggest task was splitting up and formatting things in a way I wanted. Lines were cut a little differently than what the translations provided, and we added in a bit more punctuation here and there.
The first phase of my storyboard, image generation, was a lot more gnarly than expected. In this process, I wanted to programmatically create the lyric lines. Similar to Sweet Regret, I could have done this in Photoshop if I really wanted to, but making changes would be tedious and difficult, and I wanted to play around with a lot of iteration.
The first problem I encountered was finding a suitable graphics library to output text to an image file. The first one I used, pngwriter, did not support alpha. Great. It took me a while to realize that, and if I recall I did some source compilation to try and get everything working.
My next choice was CImg. This one had problems too. The issue this time was that it did not have built in capabilities to handle custom fonts. Honestly, I may have been better off trying to work with lower level libraries like libpng and freetype. At least I'd learn a ton from that. On the other hand though, I could have dug myself deeper into a rabbit hole doing that so I wanted to find a library to suit my needs.
Eventually I settled back with the good old SFML. I was quite familiar with using this library for games, but it didn't hit me that it could help me out in text generation as well. Setting it up and getting it working took a lot less time than the other libraries since I was familiar with it already. Using the functionalities was also pretty easy for the same reasons.
With the library set up, I could finally do the actual generation. By now, I think school was already out, so I was working over break. I went out and grabbed about a dozen different Japanese fonts that looked pretty cute. Each line used a randomized font from this pool. I wanted each line to display the Japanese kanji and its English translation underneath.
Royce was against having any English at all, but as someone who didn't speak Japanese, I definitely preferred having subtitles to help translate. Not all of the fonts were suitable for the project though, and I had to remove some. The main issue was that a few of them didn't support some kanji and would have blank letters.
One solution was having Royce help correct these errors by simplifying the kanji down to hiragana. He was not a fan of this, however, citing that reading the text would be more difficult and messy. In the end I removed about half of the fonts that did not have kanji and used the remaining for the project.
It took me a while to figure out unicode/utf-8. Even now, I don't think I have a firm grasp of character encoding, but I have something that works so I'm not going to complain. The way to handle it used 3 or 4 lines of some gibberish setup code that I referenced from through some stackoverflow post. I don't know. Encoding is weird.
I wanted generation to be slightly randomized. On top of choosing a random font, I made the text widths and heights a little random as well. The English text was forced to be something like 60-80% the size of the kanji. To account for anything from one character to a long line of characters, I put some max limit constraints so things wouldn't get too big.
Randomizing the sizes led to some problems. Even now, I don't think everything is perfectly fixed. An example of this is how some of the English text lines are quite small and difficult to read. This was a combination of constraining the font size and also certain fonts naturally being small. I decided to let this problem slide. I don't think it was worth my time to try and fix special cases here.
Also, the way I found the max size of a text line was probably not optimal, but it's the quickest solution I thought of. In order to find the font size, I drew the text at a small font size, found its bounding box, compared it with my width/height limits, and then repeated the process at a bigger font size if it was under the limits. If it goes over a limit, the loop stops and we return that font size. Image generation took some time probably because of this alone, but the bulk of the process was still in the actual making of the image itself and not this testing.
Alright, so now I had some image files I could work with. The next part was doing the math to move everything in the storyboard. This was a lot more complicated than I thought. I could have used the SFML vector classes, but I decided to write my own. It was an educational experience, I suppose, but errors cropped up here and there, and it took me a while to track down these hidden problems.
My first major task to tackle was to prevent overlapping between text lines. To do this I wanted to compare collision areas. My first attempt was using circle colliders because that was the easiest to implement. All I needed to calculate was a radius for each text line and then I could use that to find the overall circle.
Checking collision between two circles is easy enough. You find the vector between the two center points of each circle. If this vector's length is less than the two circles' radii added together, you know there is an overlap. This was something I picked up from a friend at VGDC, and it worked well for my previous games.
Unfortunately, it didn't look so great in the actual storyboard. The problem was that there was way too much extra space. If you can picture a circle surrounding a line of text, you can imagine that there's a lot of blank space on the top and bottom areas. I wanted the lines to have as little space between them as possible so I needed to rethink my collision formula.
After researching a bit, I applied a version of the separate axis theorem that I found a reference of online. My vector math was not very good so it took me a while to understand some parts. There're a quite few steps involved to applying the theorem in code. None of these were particularly too complicated, but because there were so many parts, I often had small errors here and that I couldn't catch.
With collision in place, I could now calculate near perfect placements for line positions. First we placed the new line into the center of the screen. Then I chose a random direction to move the previous line to. I used a random value between 0 to 359 for the degrees possible. Then, I slowly moved the previous line outwards along this direction until the two text lines no longer collided.
From this, we know that the previous line was moved far enough way, but this did not guarantee collisions with previous lines before that. So now we have to loop through all the previous lines, translate them similarly and check if there is a collision with the center line. If there were no collisions, we could move onto placing the next line. Otherwise, we'll redo everything, starting with choosing another direction.
This was a somewhat time consuming process, but we didn't have to handle too many lines, only around ~50 I believe, so it was manageable. Sometimes the program would get stuck because of having no room to position lines. Imagine a case, for example, where the generation decided to spiral inwards, and when you gor to the center of that spiral there's no more room to position anything without overlaps. These error cases did pop up, but only occasionally, so I just ignored them and restarted the program.
There were some other possible ways to handle placements. Another idea I considered was possibly doing something like a collision simulation. The idea was that you would randomly throw the lines into a space and then have some kind of a gravity pull to the center of the screen. The lines would then compact together and form a tight knit ball. I could then read the positions and rotations of all these objects and adapt that into the storyboard.
The pros of this method was that everything was very close together. There's a higher chance of seeing previous lines around the edges, and that was something I wanted to push for. With the procedural method now of generating the positions, I just chose a random direction to make a new line. There were no weights to guide the placements with the current method. If I did apply any preferences to the direction, I expect the generation to take a lot longer and for stuck cases to pop up a lot more, perhaps to an unmanageable amount.
One of the reasons why I wanted to have things close together was because I was thinking of a cool effect to do at parts of the song where you zoomed out and viewed all the lines clumped up together. I never got around to this, however, mainly because of an osu! ranking restriction. One of the rules stated that you should be careful of the number of images you're loading onto the screen. Loading a lot of images at once can cause lag, something very frustrating to deal with in a tense rhythm game.
I couldn't afford to keep all the lines drawn. Even if they were off screen, they still soaked up resources. Ultimately, I limited the project to only keep track of the last 5 lines. In the future, I don't know if I want to worry about this kind of limitation. Without it, I would have loved to give the zooming a shot and create some prettier effects. It might not get ranked because of it, but if I want to achieve something, I think I should pursue that without regard.
Another problem for the simulation method was figuring out how to stick things together. If I let a simulation go wild, lines may be separated from one another, and I want to make sure each line can flow to another adjacent one. In order to implement this, I imagine I'd have to code some kind stickiness property that forces two lines to stay connected together. Thinking about it seems interesting but probably more work than I would have liked.
A final problem was representation. If I did the simulation method, I would get back a view of all the lines in the positions I'd like them to be. For the storyboard, it was my job then to focus the camera to each position and in the proper rotation. This, however, was slightly backwards from how a storyboard worked.
In the storyboard file, you specified where, when, and how a sprite, in this case a text line, should appear. You don't manage a camera at all. You can imagine that the camera is sitting perfectly still and all you're doing is moving sprites into view. It shouldn't take too much work to convert camera to local sprite transformations, but if possible, I didn't want to think about that.
There were other considerations as well. Perhaps the simulation would take too much processing power or time. Calculating 50 object collision against each other every frame doesn't seem perfectly optimal. 50 wasn't too bad, but I'd like to reduce generation time as much as possible.
I think the simulation would be an interesting project to work separately on. It might be cool to have some kind of GUI to work with and see things in action. Or hey, maybe I should just adopt another library for this kind of stuff. I've never worked with Box2D before, but from what I've heard it seems like a good option for this physics stuff.
Anyways, back to the storyboard, on top of movement, I also had to handle rotations of text lines. The local rotations were pretty easy to handle since osu! deals with that directly. Where it gets a little trickier is if you want something like a sprite rotating around a specific point.
If you watch the video, you can see that the previous lines rotate around the center point. The local rotation of each line is handled by osu! directly, but the positions aren't actually rotated properly. To cheat the process, I just linearly moved the surrounding lines to their end position. I didn't want to deal with calculating intermittent positions and things of that nature. The overall result was alright and not too noticeable, so I kept it as is.
With positioning now set, the next step was timing. This I did manually. I opened up the song in game and used the game timing to check when each line should appear. These timings were saved to a separate doc that would get parsed in as part of the storyboard generation. Doing this, I noticed that there were some slow sections to the song that didn't have any vocals. I didn't want to have a previous line hang around forever, so to account for that I put in the Du du du du~.
Another small thing I added was the background spiral. I felt like I could put a little something more into the background since it seemed a little empty. I decided to incorporate the iconic spiral from the song. There weren't any available images for the spiral by itself so I had to make one from scratch.
This I did by taking a screenshot from the music video that had a spiral inside of it. I imported this to Photoshop and blew up the image several times its size. Then I traced over the spiral roughly. It didn't need to be very exact; the original had a hand drawn feel to it already. Finally, I centered it properly and that was that.
The last thing I did was coloring. The colors I picked, pink, yellow, and blue, were also taken from the original video. For some additional colors I also added in the neutral white and black into the mix. I thought that making each line change colors may have been too excessive, but I think in the end it was fine and looked plenty good.
I wanted each consecutive line to have different background, spiral, and text colors, so I randomized the colors with this constraint in mind. However, doing this I ran into some problems where the contrast was too washed out on some combinations. For instance you can imagine the result if a bunch of lighter colors overlay on top of each other.
So what I did was I made a bunch of special cases to handle these scenarios. Basically, this entailed making sure that if the background was lighter then the front colors must be darker, or vice versa. For the most part it solved the issue. Even now there are still some combos in the video that are a little hard to see, but it's not too distracting.
That's pretty much it. This was a really fun project to do. I love making special effects like this and making things pretty. I could have worked on adding more, but I'm satisfied with the result, and I think my team is too. I practiced a lot of vector math, which wasn't exactly too fun but sure was interesting to work on. Most of my problems stemmed from tracking down errors and debugging for days. I'm considering writing tests in the future to help prevent mindless searches for errors.
With the storyboard finished, the project was just about done, but I wanted to add one more piece to the puzzle. For Silicon Heart and Sweet Regret, we had playthroughs of the songs, and I wanted one for this map as well. Aaron was happy to help again, and he did two videos this time. One video was a playthrough of Kenny's map. The other was, upon my request, a video of the storyboard by itself. I was pretty proud of my work and wanted to have a snapshot of it saved somewhere.
This concludes about everything. I had a ton of a fun working on the storyboard, and I would love to work on another one again given the time. I swear... I'll work on one again one day. After finishing all these project write ups I'll go back to storyboarding. One day, one day, I hope.
Working on the picture was... alright. For my current self, drawing is fun every once in a while, but art feels really taxing on me these days. It's a really time consuming process that has a beautiful end result but takes a ton of effort. I don't practice much anymore, so that's probably why.
I think everyone learned a lot and had fun on this map. Our beatmaps were probably not the best of quality, but part of that is just due to our inexperience. With a lot of new people, inexperienced and experienced, coming into the club, I think beatmap projects will do a lot better and be a lot more exciting. Hopefully the club continues to produce maps each quarter. I'll stop by and help out if I'm available.