In the last devlog, I talked about the latest area’s level design and the pause menu’s slight UI improvements.
Since then, I have, amongst other things, worked on the chase levels. These levels are particularly huge (about 7 to 8 times the size of a regular level), and they consist in continuously running away from a moving wall of sawblades, while activating and killing the various mechanisms and enemies on your way.
The wall of saw-blades is technically a surface to which I drew the sawblade objects and a primitive to hide their back.
As the level is mostly composed of black walls, I needed to find a way to make the sawblades stand out; I decided to add a red outline to the entirety of the surface.
There were mainly 2 ways of doing this:
– Using a shader
– Drawing the surface 8 times in 8 directions with a slight offset
The obvious choice was the shader, but I did consider the second option for a while as the outline looked smoother on the edges (see the circled green areas).
Ultimately, with such a low outline width, it didn’t matter (especially as the sawblades are almost constantly spinning at a fast rate)
Getting the movement of the sawblade wall right was trickier than expected.
The general idea was to make it move faster the further away it was from the player, so it caught up to him, never being too far behind, and always in-view.
I had to take a blind shot at the specific speed / distance values and adjust them after play-testing, but this process took an unexpectedly large amount of time.
After having set up a rough tree of if / else statements, I proceeded to use Regressi (a software I usually use in physics class) to run a regression on that data, interpreted as points on a graph (the x axis being the distance between the sawblade wall and the player, and the y axis being the speed of the sawblade wall).
I then used the outputted function to smoothen out the speed variations of the sawblade wall and replace the if / else tree:
I suppose I could’ve gone the extra mile and make all of these values dependent on the player’s speed, but it didn’t strike me as necessary.
With the basics settled up, I moved onto level design. In the last devlog, I said I wanted the chase levels to be more of an exciting breather after the complicated, tight and cluttered, puzzle-ey levels from before. This didn’t end up being completely true.
The level design sure is straightforward, and doesn’t require much thinking, but the difficulty is still brutally hard.
Yet I had way too much fun playing through the layout I had roughly built, despite dying dozens of times; so I figured I might as well make these levels the climax of the game before the final boss, which will be preceded by a series of dark and calm levels acting like antechambers.
While the previous levels (almost) all had a new mechanic that served as a starting point for my level design, I was left clueless with this one. I found it challenging to come up with bits of layout that didn’t have anything special to them but still were enjoyable to play through. It took once again a lot of play-testing to get it somewhat right (RescueTime says I spent 11:31 hours in-game during that week – that’s a lot considering the ratio with the 22:29 hours spent in Game Maker).
Speaking of the time spent in Game Maker, most of it was dedicated to decorating the level manually. Given the large size of the level, it was a tedious task to place the tiny decorative tiles, while making sure their placement looked “random enough” – this meant no copy pasting, no reusing similar looking configurations, avoid aligned objects. Having an algorithm do it for me would’ve saved me a ton of time, but I don’t think I have the knowledge nor level of GML mastery to code one; and the time it would’ve taken me to do it wouldn’t have been worth it at this point in late development.
Here’s a time-lapse of me placing said decorations in the first half of the level (2 hour long stream – check out my twitch):
And while placing the static decorations was a boring task, coding a foreground / parallax system was a lot more fun. I had already written the scripts drawing the various structures I would display in the foreground (more on them later), so all I had to do was organize everything in a ds_grid to store their attributes, manipulate their position based on their depth attribute, and draw them accordingly.
The final result was satisfactory.
However, I had decided to make 2 of these chase levels, so the job was only half done.
The process of building the second one was pretty much identical to the first one, besides the fact that I had to make some adjustments to the sawblades wall’s code and the foreground system, so they could support the tilted level design:
In order to avoid overwhelming the player too much with 2 chase levels in a row, I built the second one to be a bit shorter and easier (not to mention the player will already be trained to the fast-paced gameplay with the first chase level)
The video above also showcases how the music evolves through the levels.
The main track has been divided in 3 loops – 1st for the intro, followed directly by the 2nd one looping in the first level, which is stopped in the second level, in which the 3rd loop is used:
I managed to make it work with my poorly-coded sound system, but there are some fundamental problems with it:
– There is a slight pause before the song loops or transitions into another song, whether the audio file is an .mp3 or an .ogg
– The volume changes for seemingly no reason when I switch from one track to the other
These problems are so baffling to me that I decided I’d completely rewrite my music control object and scripts, in a near future, once I will have thoroughly studied Game Maker’s audio system in the manuals.
Besides working on those chase levels, I also worked on some short “cutscene” levels, notably one way back in which you get out of the machine-gun:
Unexpected complications arose from making the player be able to walk around the machine-gun freely, such as collision and depth sorting for the player, his laser, the inside of the vehicle, and its outside; so it took longer than expected.
These “cutscenes” are still full of placeholders and some of them spoil important plot-twists, so I’ll refrain from sharing them all.
The other “big thing” I worked on this month was the main menu.
I had started working on it in June, when I coded different transitions between the title screen and the main menu. I went through different iterations, but it all started with this:
The camera was supposed to zoom out of the title, revealing a black space around it in which the main menu would appear. Getting that camera to work properly turned out to be a bit tricky and I couldn’t be satisfied with the results no matter how I tweaked it.
I decided to go with the menu simply appearing through an abstract mask:
And to add a bit of flair I rendered an external animation of the logo compressing itself into a lozenge, which lead to:
At that point I already had roughly sketched how the main menu would look, and started coding it in-game:
The first step was to tackle the rotating structure. I did it by expressing the scale and the x position of each ball in function of its y position, using cosines.
During this process I finally got comfortable with using trigonometric functions as a way of looping things by realizing that I can build any periodic function with
cos(x * (π/period) – offset) * amplitude, so I applied that to literally everything on screen. I also figured I could easily transform a cosine so it waves between 0 and 1 with (cos(x) + 1) / 2, and vice versa. This opened up a lot of shortcuts later, as I could use it inside lerp() or merge_colour() functions. Even better, I found this quality script (on twitter, I’ve been searching to find the author again but couldn’t) that transforms a value from one range to another; again, opened up a lot of nifty shortcuts sparing me the boring if / elses for a better web of interconnected local variables.
Meanwhile, I got to play Just Shapes & Beats and was impressed by its UI design. And for no reason whatsoever, the menu started looking more and more like that one:
Just Shapes & Beats‘ gradients also inspired me to make a rudimentary lighting engine (poking gradient holes on a black surface) – I’ll improve it later so it also supports colour.
The bands still felt a bit bland though, so I tried filling them with random moving stuff, again, iterating through different ideas (almost all of them were scrapped before I could even record a .gif):
And with that being done, the main menu was complete!
However, I had yet to do the save selection menu. This time, it’s Persona 5‘s incredible UI that inspired me, more precisely these polygons with freely-moving vertexes:
I was unsure about how to use them in TAWBS, as the art-style is nowhere near as crazy and chaotic as Persona 5‘s, but toning the effect down to just a smooth wobble turned out pretty fitting! After a few hours and different iterations (see time-lapse near the end of the page), I ended up with this:
I proceeded to then make the save slots selectable. Originally I wanted to have particles fly out of the save slot, but then I remembered a wise game developer (Grog) once said on stream that a good way to add polish to your game is by making stuff happen with an offset to them. So instead of having the particles pop out at once, I made them spawn one by one around the lozenge; eventually, I made them immobile so they looked like a trail of squares moving around the save slot:
Laziness dictated that it would be easier to have the enter button select the save slot and transition the screen into gameplay, while the backspace or delete button would delete the save slot data. But that would require to somehow display the controls on screen, which would clutter it up – at least I couldn’t wrap my head around how to make it presentable. I decided to turn these 2 options into buttons rather than keys:
Delete buttons can easily be accidentally pressed, which is why most video games and softwares prompt a “Are you sure? -Yes/No” confirmation. I did not feel like making yet another menu with 2 buttons for that, so I decided to go with the “hold button to confirm” method, stretching the black polygon, filling in the outline with pink, and glitching out the level preview (thanks to a great shader made by Blokatt).
Finally, the play button has a simple animation that could probably improved (but I’ll leave it to that for now):
Here is the final result in one video:
The video also showcases the dynamic vertical re-orchestration of the music – which is an unnecessarily fancy term to describe a simple technique:
– Re-orchestration means that the music changes
– Dynamic means that the music change happens based on actions in-game
– Vertical means that the change is made by overlapping different layers of sound on top of each other and varying their volumes to enable or disable them, rather than jumping to a change inside of the track.
The very talented musician ThaPredator made 2 versions of the main menu theme (a light one and a dark one) that could easily be overlapped as they use the same base, which is what made the effect possible.
And that is all of the work on that has been made on the main menu. It’s all in one single object, which come to think about it is probably one of the largest of the project.
There are still some problems with it:
– The lack of a difficulty selection menu when choosing a new save slot
– The settings menu being inaccessible: will redesign it completely for both the pause menu and the main menu
– The bad file management: will have to divorce .ini and marry .json, the GM masters have insisted long enough
– Some other bugs like this one:
If you’re interested, here’s a time-lapse of the 2 streams in which I built the basics of the save selection menu. Most of it is just solving bugs and not getting anywhere, like that time when I tried to draw a thick polygon outline with 4 primitives drawn in a loop instead of drawing the outline on another surface by using bm_subtract…
Additionally, as I was in a UI design mood, I completely redesigned the ammo HUD!
Seeing sprites rather than text is more visually striking, and the fact that it’s constantly moving also makes it more visible. I’ve noticed many play-testers on stream completely miss the HUD and ignoring its existence; but knowing how much ammo you have is vital in the later levels where puzzles are sometimes based on ammo management.
As for the “war exp”, it has become useless as its meaning was dependent on the story, which happens to have been slightly modified lately.
I still think there’s a bit of room for improvement but I can’t precisely put my finger on the problem – I’ll postpone that to later.
That’s all for this devlog!
I will be gone on vacation for the month of August, so there will be significantly less progress, but I’ll try my best to be productive in the few sessions of gamedev I’ll have.
Very many thanks for reading this through; if you enjoyed it, don’t hesitate to follow me on twitter or share my work around!