The Mezunian

Die Positivität ist das Opium des Volkes, aber der Spott ist das Opium der Verrückten

Boskeopolis Land: Let’s Code a Crappy 2D Platformer Like Millions o’ Other People on the Internet & Lose Interest & Give Up Only a Few Months In, Part XXXVIII ( Boskeopolis Underground )

¿How long have I put off this post? I believe I was close to done with this level’s general design not long after my last post, & ‘pon just checking was surprised ‘twas only a month ago, e’en though it felt like much longer than that. Good: the longer life feels, the slower comes death. In fact, I distinctly remember I was finished before the end o’ that SGDQ thing. Thus, most o’ July was spent refining this level’s graphics, which always takes the longest, & irrelevantly creating options screens ‘cause I was getting tired o’ playing these levels with a keyboard.

As the video shows, this level is a rather long maze level1 wherein you go back & forth ‘tween 2 rooms through sewer holes. As the maps below show, the sewer holes correspond to each other — using a sewer hole literally changes your map without changing your position @ all.

This time I didn’t bother editing the video, since it wouldn’t cut out much to be worth how awkward the abrupt cuts would look. ( The downside to my smoothing out the graphics &, ‘specially, adding audio is that it makes it harder to make clean-looking cuts: before the fade-outs & music, those message screens made cuts stupidly easy ). I tried to double-dip the 1st showing o’ the level with getting the gem challenge, but kept making mistakes grabbing gems, forcing me to go back round. Unlike most levels, I made this 1 force you to get every gem to beat the challenge. This is balanced by the level itself being calm & easy to beat, once you figure it out, ‘specially for what’s planned to be a 4th-cycle level. There aren’t e’en any enemies, so it’s literally impossible to die in this level. “Soupy Sewers” is harder ( ‘pon recently playing it & “Flush Flood” I’ve found that it’s harder than that level, too, which was less intentional ). I don’t mind it being a bit o’ a breather level before what I plan to be mo’ challenging levels following.

While I like how subtly winding most o’ the middle part o’ the maze is, I don’t know how to feel ‘bout the hidden key: it feels a bit cheap. The fake spike trap, too. Granted, it’s such an obvious hoax, since it’s the kind o’ trap that’s impossible to fall in accidentally; but making seemingly solid blocks act move-throughable as a puzzle always feels somewhat cheap to me.

Also, I feel like I might’ve made these rooms too rectangular. It’s not as if I didn’t have the sloped blocks already I could’ve used; the map’s just so packed together that I felt I couldn’t do it without having parts bump into each other. That said, looking @ it now, I could’ve had some o’ the vertical parts have sloped parts. I probably should’ve had that long block-climbing section have slopes ‘stead, since that part’s bland, anyway.

I love how I went all out to put all the moving water detail & the detailed background, only for much o’ it to be hard to see due to the darkness. Some may feel making things too dark is a cheap gimmick & that I should be deprived o’ a Twinkie, but this level has no serious platforming challenge, so it’s not much o’ a burden, & I actually despise Twinkies. A’least I added that pointless spotlight @ the last minute. I once planned on having a mines level with a “race to hit switches to keep the lights on” gimmick, but wisely decided that that gimmick is o’erused & obnoxious. “Blackout Basement” is 1 o’ the most bullshit levels in Donkey Kong Country.

This time I didn’t bother making a looping or tiling background, but just made a big image that fits each entire map. This made making the background easier in terms o’ logistics as I didn’t have to think ‘bout how to make it seamlessly repeat without being obvious that it’s repeating or do a bunch o’ complicated layers o’ backgrounds or create dozens o’ useless blocks to add li’l details like the posters & graffiti — ‘twas as simple as just drawing a picture, with no programming calculations needed @ all. I was surprised this level runs as smoothly as it does ‘cause o’ this. I’m not exactly sure how SDL’s textures work ( the downside to black-box encapsulation, as many stern C, & ‘specially assembly, programmers bemoan ), but I know the way the image files themselves work, by being PNGs with large parts o’ each image not being filled in ( parts ‘hind sold blocks ), the image files aren’t as heavy as they could be @ that size.

The graphics that took the most work was that sewer hole transition animation. Worse, it required me to add complex code that verges on entangling spaghetti. In my defense, I did try to isolate the code to the EventSystem class as much as possible; but I still had to add an otherwise needless render function to the EventSystem to be called by the LevelState every frame, though it’s only used in 1 level, & did had to add some extra code to the PlayerSprite class to take it into consideration. Also, now that I think ‘bout it, the EventSystem class is looking eerily like a God class. & as the wise programmer Bakhunin said, if there exists a God class, we’ll have to kill it2.

On the other end, it did save me from having to painstakingly add every warp point to the level document: since I had to add an extra, heavily-reprogrammed version o’ the warp code to deal with all the differences, I could easily change it so that it just changed your map without changing your position. This also made warping smoother as your corresponding position in the other map is the exact same, by the pixel, rather than being a specific position in the middle o’ the corresponding sewer hole regardless o’ where you were position on the other side before warping.

‘Nother boring detail: in order to minimize memory waste for this 1-level thing, I made the sewer hole code — it’s image information & such — a pointer to an object so it wouldn’t increase the size o’ the union it’s in too much. But for a while I messed this up in a subtle way, though easy to solve point: I made sure to clean up the pointer whenever the EventSystem object is reset, but forgot that sometimes it isn’t reset but straight-up eliminated through RAII when leaving a level ( the solution being the typical RAII solution o’ a destructor ). This is why it’s good to test with valgrind a lot.

Actually, valgrind brings the final point o’ my process: finally implementing the options screen. For the last year or so I’ve been focusing mostly on just completely the levels & planning to implement these other things when the main content was done, but I got sick o’ having to use a keyboard when playing all the time, & for some reason decided to make an options screen to remap keyboard & controller controls ( as well as save & load these mappings from a config file ), & before that a way to change screen resolution through options. I’ve been thinking o’ doing more o’ these other things to better use time wasted in designer’s block, as there’s still a bunch o’ things I want to implement, like shops in the o’erworld that sell things from extra hit points, bonus levels, improved oxygen, & other things. In fact, I’ve just thought it’d be fun if, after beating the game, you could buy Goldeneye 007 style cheats that could make you ridiculously faster or give you a double jump or other things ( which would disable getting time & gem scores when using them, ‘course ). You could say this ultimately comes from a transition in my expectations for this project: from a mindset that wants to ensure I stay focused & actually finish this project to an acknowledgement that I’m definitely finishing it @ this point & a desire to optimize the use o’ my time.

Actually implementing the joystick didn’t take too much time this time ‘cause I already did it before, I just commented it out ‘cause it causes a memory leak, a’least according to valgrind, that I can’t fix — it seems to be on SDL’s end, not mine. After wasting way mo’ time that I’m happy ‘bout trying to upgrade SDL on my computer, I’ve come to accept it. You could debate whether it’s a true memory leak, since it’s a single “loss” o’ memory that will ultimately be cleaned up by the OS when the program is closed. Memory leaks are only truly meaningful when they’re a repeated loss o’ memory, since that is what leads it to actually cause problems: creeping loss o’ memory till you ‘ventually run out.

However, the 1 serious problem is that I still need to watch out for my own memory leaks, which do still fall into this problem; but ‘cause valgrind is whining to me ‘bout SDL’s joystick code, it clouds my own memory leaks. My solution this time is simply to keep all joystick code ‘hind compiler codes so I can temporarily turn off joystick functionality when testing for memory leaks. The only downside is that for some reason I have to clean & recompile my whole project whenever I want to make this compiler change. You’d think just deleting the object files for the input & main files would suffice, since they’re the only files that acknowledge any o’ this code. All everyone else knows is some function that returns some entry to some array that is no mo’ tied to the joystick code to key presses, with the controls options knowing ‘bout some other functions that send some abstract enum value corresponding to an action to the input & taking in strings from input. No one else e’en knows that “joysticks” or “key presses” exist.

Below is a video demonstrating the new exciting options screen:

As usual, I had to remake this video many times ‘cause I kept noticing subtle aesthetic flaws like missing sound effects or not-perfectly-spaced text.

Anyway, all that matters in all this is that I 100% kept my promise & did “Boskeopolis Underground” next, & e’en kept it @ that name, though I did consider renaming it to something like “Septic Labyrinth” or “Gutterly Annoying”, since “Boskeopolis Underground” sounds rather bland & the reference will probably be lost on everyone. But those other names sounded e’en stupider, & the last thing we need is ‘nother alliteration name. I’ve gotten sick o’ those. Yeah, it’s a cute reference to Rare — but sometimes cute references just fall into laziness, ‘specially the “Food Place” pattern ripped off from Kirby. That’s a cute reference when you do it in literature; but in video games, then it just becomes incestuous. Honestly, I’m thinking o’ renaming a bunch o’ the levels I’ve already done with lame names like “Milky Mountains” or “Soupy Sewers”.

No promises for what’s next, though, as I’m working on a few new things simultaneously. However, close candidates are “Dark Sahara”, the 3rd-cycle desert level & last I need to develop, & “Good-Ship Lifestyle”, the 4th-cycle pirate level. For the former I’m still thinking ‘bout how I want it to end, & I’ll probably finish it 1st; the latter has the much mo’ arduous roadblock: I’m thinking o’ giving it a boss, which’ll involve a lot o’ complicated programming. Then ‘gain, I may separate the boss as a separate “level” — not the least ‘cause I don’t want a player to have to go through the whole level & boss in 1 life & would rather avoid adding midpoints just for 1 level. I still want to finish “Petrol Pond Place” & maybe “Mt. Volcocoa” this summer, but still haven’t figured out how I want them to be designed. With “Petrol Pond Place” I toyed with a tube you could move round in, but found trying to implement it difficult with this game’s rather rigid block-based collision detection that make walls thinner than 16 pixels infeasible ‘less I add or change a lot o’ code.

Posted in Boskeopolis Land, Programming