The Mezunian

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

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 XXV

Porcelain Dreams

As the video shows, the main gimmick is faucet handles attached to thin air ( or thin water ) that raise or lower the water to their level — a blatant ripoff from Super Mario 64.

I’ve actually been working on this level for a while. I’m sure I’ve mentioned it in earlier updates, might’ve shown screenshots, & you would’ve seen the unfinished level if you looked @ the source code or paid attention during level select screens.

The problem I’ve had with this level was that I just felt like ’twas too small, too insignificant. Originally there were no enemies & it took ’bout 15 seconds to beat. You just hit a handle to move the water up so you could jump up some place, go down, get to the end so you can raise the water higher, & then reach the goal. For a while, I did have 2 enemies round where the eels are, but they were awkward spikes that jutted out & in & were impossible to dodge consistency due to their dicey hitboxes. The eels mostly fix that — their hitboxes can be questionable, but they leave a wider gap ’tween their runs through the pipes, so you’ll probably only hit them if you’re rushing & mismeasure them by a few pixels, rather than trying to guess which milliseconds in the spikes’ second-long pattern count as harmful or not.

Actually, I should admit that the video isn’t accurate to the current version o’ the level. If you pay attention you’ll note a subtle graphical glitch: sometimes the eels go past the end o’ pipes, popping back out. I fixed that by lengthening those pipe ends, but after I’d already recorded the video & o’errode the save. It’s probably better this way, since it saves evidence for the original flaw.

The future

I’m currently working on ’nother sewer level with 2 gimmicks: being able to warp to the other side o’ the screen from the sides, like Mario Bros., & constantly-rising water that you need to keep ’head o’ to avoid drowning. I’ve also been trying to draw graphics for a train level that’ll probably be the 2nd-cycle desert level. My planned gimmick for that level would be to make Autumn be able to shoot enemies & to have a bunch o’ enemies shooting @ you, forcing you to hide ’hind crates. Just thinking ’bout all that I’ll need to finish that level, I can already tell that it’ll take a’least a month.

I had the idea to have a space world, but that would require reorganizing the map, so I don’t know. Also, transitioning from sky to space to ice may be awkward. Plus, it may not be that creative an idea.

Download lame source code

Posted in Boskeopolis Land, Programming

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 XXIV

Tubboat Blues

I plan for this to be the 1st “pirate” level, e’en though it actually takes place in a bathtub.

I have mixed views ’bout this level. I put a lot o’ effort into it, — which is a way o’ saying ’twas a pain in the ass to make — but I don’t feel like it’s that great. It’s certainly worse than “Sleet Streets”. It’s janky, exacerbated by the fact that it’s a water level. The hitboxes for the Peanutbutterfish aren’t forgiving ’nough, caused by them being blocks ’stead o’ sprites ( you can’t specify hitboxes on block types ), & trying to jump out o’ water can be hard as Autumn sometimes just doesn’t want to. I think the problem is that I didn’t connect the difficulty o’ maneuvering through the Peanutbutterfish without getting hit & the problem o’ limited time underwater. You have to be careful to avoid hitting them, but you can’t afford to spend too much time being careful or you’ll drown. Deciding to make the lifesaver platforms ( which are obviously sprites ) bob up & down also bit me back as it makes them a pain to maneuver on, as the way they affect your height & whether you end up in water ( whch heavily affects how you move & jump ) is seemingly random, e’en though the code that determines how they move isn’t based on randomness @ all. & I held back when programming them, too: I originally made it so you could nudge them horizontally, but found that that was too janky.

In short, this video took a while to get right. It doesn’t help that the temperature is in the 90s Fahrenheit. The 1st time I tried recording I got so frustrated from the heat that I tossed my MP3 player ’cross the room & had to go looking for it the next day.

In fairness, you can ignore the underwater parts with the Peanutbutterfish if you’re not going for the gem challenge. The only reason they’re there is to discourage players from just swimming under the lifesaver sections ( originally there was a “Quadrapus” in the water that would chase you, making it so that being in the water too long would hurt you; however, I found that that made the underwater secrets too hard to get as it’d box you into those pipe sections ).

The visuals was where the most effort went, & is where I feel most mixed. I was proud o’ the “Peanutbutterfish” idea. I vacilated ’tween underwater mines, which seemed too boring & plain, & jellyfish, which seemed to be ripping off Super Mario Bros. 3 when I came up with this twist. E’en though I added the glowing outline to them to show that they’re electrified, I added spikes in the hopes that it’d better show that they’re dangers, as otherwise underwater jars look like benign items ( glowing isn’t sufficient to show danger, as that same glowing effect is on the presents in “Sleet Streets”, which are good ).

The water drops & faucet irk me — not the least o’ which how cliche a danger falling drops are. ¿Why does falling water drops hurt Autumn, but not whole bodies o’ it? I tried to make the water drops look like they’re splashing, but they just look like flattening paper. I also had to enlarge the water drop sprite sheet just so the flatter sprites don’t get resized uglily due to how crappy my sprite engine is, wasting extra memory.

The faucet’s janky, too. The handle & the water stream are actually 1 sprite: the sprite is the handle itself; it just has a custom graphics function to draw the stream based on how many hits the faucet handle has. The handle flashes when hit ’cause I couldn’t figure out how to show it twisting @ its current angle. I was glad I was able to get the effect, though I still feel the ending is abrupt, e’en if I made it wait almost a second after the water turns all the way off. Then ’gain, the normal effect o’ having the game just instantly flash “¡Success!” after touching the Keycane is e’en mo’ jarring. ’Nother downside to having the faucet stream be a ghost graphic with no collision box is that I wanted to have the stream push you downward ’pon touch. I could easily do that by simply having invisible blocks there, too; but making that affected only when the faucet is on would be mo’ complicated. The whole reason I tied the faucet stream to the handle was to make tying its animation to the handle’s “HP” simpler. I guess I could just make the stream its own sprite & just give it a custom type & just have the interaction code for the faucet handle check for type & change the stream’s graphics there.

I’m torn ’tween whether I think the background is too cluttered & distracting or too barren. I ran out o’ ideas o’ what to put there & just said, “I’m done. If it desperately needs mo’ detail, I can add it later”. I kept out the darkest gray color so that the background wouldn’t take too much attention & mesh too much with the foreground; but I still feel like the tiles can get mixed up in the pipes sometimes.

I do stand by the o’erall bathtub theme, & like how it works with that palette, which I think I stole from some Donkey Kong Land game. Those games have the best palettes, as they don’t use plain white & black for the brightest & darkest colors like most Super Game Boy palettes. The faucet gimmick’s just a gimmick that’s only different from a Keycane in aesthetics, & is overtly ripped off in conception from Wario Land II. The bathtub idea was ripped off from Cool Spot, which you’ll read ’bout in a week or so.

Other programming stuff that nobody cares ’bout

I programmed in controller support — & by controller support, I mean support for my particular controller. I still haven’t gotten round to doing an options screen wherein players can choose their controls. The other bonus is that this add-on causes Valgrind to say my program has a memory leak, & I have no idea why. I know exactly what causes it: the SDL_INIT_JOYSTICK code; I just have no idea why, since I close the subsystem before the program closes. It’s not a dire problem, though, since the leak doesn’t increase in memory loss o’er time — which means it’s not much o’ a “leak”, since it only happens right before that memory’s reclaimed by the OS, anyway. The anal-retentive part o’ me doesn’t like Valgrind not showing 0s, though.

In a bout o’ designer’s block I also fiddled with the sprite & block code to make it take up less memory. I found out that the Object class that’s parent to both blocks & sprites held a rectangle object for original position, e’en though only sprites use that. ’Twas easy to move down into the Sprite class, & saved the block class 16 whole bytes. I’d make a sarcastic remark, but considering how many blocks there are in each level & how oft they’re created & deleted, that could come in handy ( ’specially since I still toy with the idea o’ having every map just load every block & keep it like that, since it’d make blocks that can move mo’ feasible ).

Since most nonprotagonist sprites don’t use HP or invincibility ( I think just the faucet handle does, ironically ) or oxygen, I cut those out & put them in a separate class for that’s just used for the player. I tried to take out what I could for water physics in general, but couldn’t take out the “in_water” flag, since that is used by other sprites, such as the big ice blocks in “Frigid Frigates”. But I did slim down the sprite class a bit, which is good, as they’re quite big, & unlike blocks, they are all loaded per map in all levels.

I also programmed in oxygen & health upgrades & refined “Soupy Sewers” so that it works well with the oxygen upgrade ( without it getting winning the gem challenge is impossible & getting the diamond requires suicide ), but still haven’t programmed any way to actually get them. I plan to add some shop in the o’erworld where you can buy them sometime.

Posted in Boskeopolis Land, Programming

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 XXIII

Sleet Streets

¿Remember when I said I was working on a snow level full o’ slopes in my last update? This wasn’t that. When I wrote that I had 2 ideas for snow levels: a mountainous snow level full o’ slopes & tricky jumps & a city / snow level wherein you had to collect presents. @ 1st I was going to have the former be a 1st-cycle level & the latter be a 4th-cycle level; but then I decided that the city / snow level seemed like it’d be much easier, so I switched them & ended up working on “Sleet Streets” ’stead.

There’s so much to talk ’bout, I don’t e’en know where to start. I actually had to program in quite a few things for this level — the presents & the corresponding goal being the most noticeable. ’Twas also the easiest: I simply had to add a variable, a function for adding to that variable, & a function for checking the value o’ that variable to the inventory; make a block component & goal that deals with adding & checking for presents; & draw to the inventory based on it. A change you may notice is that I got rid o’ the word “OFF” that was always there, e’en though it isn’t used in any level yet. I’m changing the inventory so it’s mo’ context-based, to minimize clutter. Hardly any levels will use on / off switches ( so far none do ), so there’s no point in putting there in most o’ them. Similarly, while not shown in the video, going into a different level won’t show the presents counter; only in that goal will it show them.

The main mechanic I added was the ability to create a block background layer, which is used all o’er in this level. If the tiled map file has a 3rd layer, the game makes a MapLayer that is a list o’ blocks like the normal blocks, but they’re drawn in the background ( though ’bove all other backgrounds ) & they can’t be interacted with. This made having the buildings on the slopes much easier & allowed me to make Autumn appear ’hind the snow on the slopes but still appear in front o’ the buildings.

The other big thing I added were the snowman & large snowboulder sprites. The former are wildly predictable & can be hard to dodge — ’specially when coming back out o’ the sewers. Originally I planned to have them throw their snowballs upward, arcing back down, but then I decided that was less fun to dodge, as ’twas mo’ likely that they’d just go o’er your head, anyway. The snowmen still have no animation, though, which I probably should’ve changed ’stead o’ wasting time adding animation to some background portrait. The snowboulders are incredibly simple: they just hurt you when they touch you & are affected by gravity & blocks, which on slopes make them naturally fall down. Their graphics are also simple: just a single image that rotates based on how fast they’re moving. Their collision is buggy, though: you’re s’posed to be able to stand on them safely, but a lot o’ the time you’ll get hit anyway, probably from scraping gainst the corner o’ their hitbox while going upward. Also, if they run into you when you’re to the left o’ them, they’ll oft smash you inside the ground blocks. It’s easy to pop out, though, & it actually makes a great effect.

A minor effect: background & foreground layers can now have alpha, which was done so I could have the transparent fog in the sewer section. I have concerns that it may be too hard to see down there, though.

Most o’ my time was probably spent making the graphics, as I wanted it to look nice. The problem is there are always mo’ details I can think o’ to add. Right now I remembered that I ne’er made wall scratches to add variety to the plain flat background o’ the inside sections.

I do wonder ’bout the placement o’ this level in the 1st cycle & its difficulty. It’s not too hard, but it can be quite easy to be killed by the snowmen, the penguins in the sewer section, or the falling snowboulders. The problem with the last is that you’re going uphill & the camera doesn’t leave much padding ’tween Autumn & the top o’ the screen when pushing gainst the camera limit simply ’cause there’s not much vertical space. Thus it’s easy to get ambushed by a snowboulder. My main tactic is to hold the W button to keep pushing the camera upward as I go up, but that’s awkward & sometimes my jumps don’t jump ’cause I can’t push on that key hard ’nough with my hand sharing Z & W.

While the level isn’t that hard — probably still easier than “Cotton Candy Clouds” just before it — it is so far the longest level, which makes death mo’ frustrating, & thus makes the level feel mo’ difficult, which is what matters. My goal was that it was s’posed to be mo’ an exploratory adventure than a challenge. Many o’ the challenges in this level, such as the trick floor in the 2nd building or the tree-climbing section, are meant to be safe to fail. However, I don’t think the snowmen & the penguins fit in, ’cause they’re actually quite dangerous. On the other hand, they add something to a level I fear may be a bit too empty. This is why I added plenty o’ health, including an infinite health box ’tween the 2 snowmen. My goal was that they would act as simply a training ground. I s’pose it still isn’t much harder than “Cotton Candy Clouds”, & it is near the end o’ the 1st cycle, so may a slight rise in difficulty isn’t too bad. I myself didn’t have too much trouble in my 2 runs, but keep in mind that I’ve been testing these levels o’er & o’er & have internalized much o’ it ( & died a lot mo’ when 1st playing ). The point is I want to avoid forcing players to redo a bunch o’ stuff repeatedly ’cause o’ simple mistakes. While I expect players to die a few times in the previous levels, my goal is for players to die a lot fewer times in this level, thus making the level length not so daunting.

An obvious solution that I’m sure someone would bring up is to add a midway point. I’ve still refused to add 1 to this game, not ’cause it’d be hard ( it’d be trivial ), but ’cause my goal is to have these levels be short like Super Mario Bros. 3, which also didn’t have midway points. The problem is that in practice I don’t think I’ve succeeded in that. I actually looked through Super Mario Bros. 3 maps as I’ve done a few times for ideas & was struck by how much shorter its levels are than I remembered — & how much shorter they are than my levels. ¿How long does it take to beat an average level in Super Mario Bros. 3? I know the average time for my levels is like 30 seconds to a minute. 30 seconds was what I targeted for the average, but a think many levels go higher than that. The 1st level takes a’least 40 seconds, & mo’ likely a minute ’pon 1st playthrough; “Mart Cart Madness” takes ’bout a minute, ’less you take the shortcut, in which it takes ’bout 30 seconds; & this level takes a’least a minute, & 2-3 seconds ’pon 1st playthrough.

Then ’gain, I also plan to have far fewer levels than Super Mario Bros. 3, — I plan to have ’bout 40 levels — so perhaps having longer, in-depth levels isn’t so bad. I think the reason why my levels tend to be longer is ’cause I want to mo’ deeply explore my level gimmicks, & I just find that impossible without taking the time. Super Mario Bros. 3 level design was simpler, so there wasn’t as much a need to explore mechanics like not being seen by enemies or a mine cart that can bounce back & forth.

I’ve also oft thought ’bout how midway points might affect gem & time scores. ¿Should I save what gems they’d collected or require players to beat the challenges without dying? ¿Do I save the time they had or find some other way to keep players from death abusing to easily get a lower time score? If I do make it so that players have to beat the level without dying to get a challenge, ¿how do I keep them from accidentally getting a midway point & having to beat the level normally just for ’nother try @ a challenge? I don’t want to make the challenges a specific level mode, ’cause I like being able to beat the challenges on 1st-playthrough; making players play a level multiple times e’en though they can accomplish everything the 1st time is annoying padding, & that’s the kind o’ cancer on modern gaming that I particularly want to avoid.

Trying to add a midway point to this level would be particularly troublesome since it’d have to keep track o’ what presents you collected, which meant either doing some hardcoded nonsense with the presents ’stead o’ the current method o’ using simple blocks or save every map’s block data for each level’s checkpoint ( which I’d have to do, anyway, if I decided to save gems collected ), which might be a memory burden. I know premature optimization is the root o’ all evil, but there’s a difference ’tween making messy code just to make a small time save that’s probably not needed vs. the instinctual aversion to messy code that has a likely potential to be immensely inefficient. I have a lot o’ lenience with this game, since it’s a very low-tech game for high-tech platforms, but that still doesn’t mean I have infinite memory; & I have run into slowdown problems. This is probably ’cause I haven’t been doing much premature optimization &, quite the opposite, this project is hilariously inefficient, not the least o’ which ’cause sprites are a messy clump o’ many variables that most sprites ne’er use — but still pay for.

Perhaps as a way to make up for “Sleet Streets” not fully succeeding @ being an easy going exploratory romp, I made the gem & time challenges much easier than most other levels. In the video on my 1st runthrough you can see I easily get the gem challenge; if you go everywhere in the level & don’t miss too many gems, you’re pretty much guaranteed to get it. Meanwhile, in the 2nd run, e’en though I make a bunch o’ mistakes, I still make the time limit with a few seconds to spare, as opposed to the very 1st level, wherein you have li’l room for error. I didn’t e’en have to edit this video, unlike some o’ the previous, ’cause I was able to do the 2 runs on my 1st try.

The Future

I may either do the “Sherbet Slopes” or the next level after “Sleet Streets”, the 1st pirate level, depending on what I feel like doing or what I have ideas for. I may end up working more on a bunch o’ graphics — I have no graphics for pirate levels yet, for instance — & take a while before I finish the next level I do.

Level Themes

For those curious, here’s the level themes I have planned:

1. City
2. Forest
3. Mines
4. Desert
5. Sky
6. Ice
7. Pirate
8. Sewer
9. Factory
10. Castle / Palace
S. Special

& these are the levels I plan to have for each theme ( levels completed highlighted in red ):

Steam Engeenius

Cycles
1 2 3 4
Themes
City Blueberry Burroughs Stormy Streets Rooftop Rumble
Forest Wasabi Woods* Bough Down Freaky Forest Windy Woods
Mines Minty Mines Curse o’ the Ladder-Splayed Caves The Minus Touch
Desert Dry, Drought Desert Desert Dare Pepperoncini Pyramid Cold Comfort Canyon
Sky Cotton Candy Clouds Value Valhalla Hoot Chutes Crying Lightning
Ice Sleet Streets Frigid Frigates Ice Mines Sherbet Slopes
Pirate Ship-2-Ship Islands Banana Beach
Sewer Porcelain Dreams Soupy Sewers
Factory Warm Up
Castle / Palace Donut Dungeon Golden Gear Solid Castle Chamsby
Special Mart Cart Madness Maybe I’m a Maze

* Now with the map I have in-mind, I’ve thought ’bout renaming “Wasabi Woods”: since the o’erworld doesn’t take place where Boskeopolis is ( which makes this game’s name a hilarious misnomer ), but in some other island, it doesn’t make sense to have a forest there names the same as the forest next to Boskeopolis. I’ve thought ’bout naming it Worcestershire Woods as a reference to some dumb series o’ microfiction I made for ¡Mega Microstories!

I wanted 10 ’cause that’s a nice even number, but as everything else, I’ll probably fiddle with it o’er however long I keep this project going. In particular, I thought ’bout having a mountain world, since the “mountain” theme is important to Boskeopolis Stories ( after Boskeopolis proper & Wasabi Woods, Mustard Mountains is probably the most prominent landmark ) & it’d make a smoother transition from desert to sky; however, I’m not sure I have many ideas for mountain levels. I did think ’bout making 1 desert level — “Desert Dare”, a level I’ve already made before but still haven’t bothered to put back in — a mountain level to leave mo’ room for a train level I wanted to do.

O yeah, I also wanted to do a volcano level. No, I think I could think o’ ’nough levels for a mountain theme. So the themes & levels I just listed are already outdated.

Other themes I might want, but don’t know if I have ’nough ideas or if I want them ’nough to include them ( I don’t want too many themes ):

  • Carnival / Fun House / Amusement Park / Casino ( I’m seriously thinking ’bout this 1 )
  • Space
  • Laboratory
  • Something Halloween-themed ( like the Pumpkin world in Super Mario Land II )
  • ¿Swamp? ( Probably not )
  • Toyland
  • Basement / Attic
  • Subway
Posted in Boskeopolis Land, Programming

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 XXII

O’erworld, Part II

What I’ve accomplished since the last update:

  • This isn’t totally related to the o’erworld, but as I was fooling round with my program I noticed the game would crash. I love how on the very day I bashed the hell out o’ the most beloved video game on the internet I learn that my own magnum opus is a buggy pile o’ shit — & e’en the cool bugs, like letting you reach the Spirit Temple @ the beginning while still a kid. During my long, in-depth look @ my code I found a bunch o’ memory leaks — some deep into the graphics & game engines & the sprite code. Since I would check my program in valgrind now & then, I don’t see how these managed to stay so long — how I could go so long without realizing that SDL_GetBasePath needs to be freed.

    However, I found that what caused the game to crash wasn’t related to that @ all, but the o’erworld ( which ’splains why the crashes hadn’t happened till now ). ’Twas caused by the same problem that constantly strikes me: I forgot to initialize a member o’ a class. To be specific, I forgot to initialize the gfx_ pointer in the OWTile class for tiles that aren’t the animated water tile ( & thus don’t have any animated graphics ). I’m used to unique_ptr, which automatically initializes to nullptr; but these use a raw pointer ’cause the water tiles are s’posed to passively share a unique_ptr owned by OverworldState. Thus, half the time the check for nullptr would fail, e’en though the tile has no real animated graphics, leading to wacky undefined behavior. This ’splains why sometimes the map would become corrupted in random ways, such as when Spiral Island spontaneously flooded once.

    &, no, don’t tell me to use shared_ptr for, well, shared pointers, as that’s pointlessly wasteful o’ precious memory & not needed if you just have a designated owner. I need to save my wasted memory on better things, like dynamically loading everything & keeping STD strings everywhere. The true lesson is to check valgrind more oft. Thankfully, I have just now & am assured that there are no memory leaks, nor have I found any random crashes. These are the problems most dire, as they can literally make a game unplayable.

  • Anyway, after all that, I finally got the o’erworld & level-select screens integrated. Now the level-select is accessed through a menu screen in the o’erworld that’s suspiciously similar to the in-level pause screen, as if I just lazily copied & pasted. & now, ’stead o’ giving you a list o’ all the levels, the level-select only shows levels you’ve been to, & selecting a level takes you to that spot on the o’erworld. My inspiration for keeping the level-select as an extra menu & having it warp you to the o’erworld spot was from the GBA remake o’ Super Mario World, wherein this mechanic was immensely convenient.

  • Saving & loading are now compatible with them. All the loading code was cleared out o’ the level-select state, where it wasn’t needed, & ’stead the OverworldState was given it. In addition, I added data for which levels you’ve been to & the most recent level you’ve been to, so that when you reload the game your level-select isn’t glitched out ( “?????” for already-beaten levels, for example ) & so the game places you on the level tile for the last level you’ve been to ’pon loading the game.

The Future

Someday I’ll get round to programming in that shop.

Also, I’m working on a snow level with plenty o’ slopes that’ll hopefully go well. The slope physics are still awkward, though. 1 thing I’ve realized is how odd the speed-capping works: it’s a simple speed cap wherein if you go faster than the cap, your speed is set to the cap with no gradual slow-down ’tween the speeds, & your top speed is based on whether you’re running ( holding the run button ). So if you jump forward while running & then let go o’ the run button, you’ll suddenly go much slower ’cause the halved cap brings your speed suddenly down. This in itself isn’t too bad: after all, you can turn round & move back while in the air, & that’s completely unrealistic. What made Super Mario Bros. so revolutionary was the way it threw ’way all the rules o’ real-world physics to maximize fun. But this also applies to slopes: you’re sliding or falling down a slide, how fast you go relies on whether you’re pressing the run button or not, which, I dunno, feels awkward. That’s a case wherein I think the break from reality went too far.

Also, though I haven’t felt anything jarring ’bout it, I’ve noticed that the ice physics should make everything mo’ wonky than expected. See, all ice physics do is decrease traction so that you slow mo’ slowly when stopping. But this applies to all movement, including upward & downward movement & flying enemies, like the bees that move up & down ( but not the circling bees: their movement is some custom algorithm that completely ignores the typical sprite speed & acceleration variables ).

Download sloppy source code, ¡now with 100% fewer spontaneous segmentation faults!

Posted in Boskeopolis Land, Programming

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 XXI

The O’erworld

As you can see, we already have:

  • Character movement, camera adjustment, & tile collision
  • Level tiles wherein if you’re colliding with them you can press A to enter the level & hold B to see the challenge scores.
  • Not only are you taken back to the map after leaving a level, you are taken back to the level tile.
  • Palette changes by entering certain areas.
  • Tile changes that happen ’pon beating levels, opening up access to other levels.

It may seem as if it’d be smart to reuse most o’ the code I already had, but what I already have for the levels is a mess, & I didn’t want to make it any messier, so most o’ the code is redone for the o’erworld, but with all the unnecessary stuff cut out. This has the advantage o’ making the code mo’ efficient, which is useful, ’cause the whole maps’ tiles ( 25,600 ) are all loaded @ once.

What I want to do in the future

  • Finish the map ’nough so that you can access all the levels, duh.
  • Show a visual o’ the map changing after beating a level, ’stead o’ justing having it already have happened ’pon returning to the map.
  • Add a shop somewhere where you can buy health & oxygen upgrades.
  • Add a bonus level, which can also be bought.
  • Possibly add the aforementioned warp zones.
  • O yeah: add a menu screen that allows one to quit the game. Also, possibly add an option to switch to a list o’ levels, but only list the levels opened so far.

Download sloppy source code

Posted in Boskeopolis Land, Programming

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 XX

Dry, Drought Desert

& this time I show off 100% o’ the level.

Not much to say ’bout this level that isn’t already shown in the video. I already showed off this “Adventure Island / Land o’ Capitalism” gimmick in a much earlier post.

Actually, the hardest part ’bout this level, designwise, was balancing the # o’ gems it gives you so that varying rankings o’ success — merely beating the level, being able to reach the diamond, getting the gem score — have a certain ’mount o’ difficulty. I tinkered with adding a gem here & taking ’way a gem there as I practiced this level & found it too hard or too easy to do certain things. This is s’posed to be a 1st-cycle level, so I want it to be easy to beat, but mo’ challenging to get the gem & time challenges. Since you’re able to make it to the goal with barely mo’ than the 1,000 needed to get the gem challenge — but much mo’ than needed to beat the level normally — hopefully I succeeded.

As I show in the video, you don’t need the secret 1,000 gems in that alcove on the wall to beeat the gem challenge. In fact, it’s probably better to not go for it, since if you don’t you’ll probably beat the time challenge in the process, whereas going to get the secret gems takes extra time. You also don’t need it to get the diamond, since that’s easier than getting the gem challenge; I just wanted to use that run as a ’scuse to show off the secret gems. That’s meant simply as a way to reward those who take the risk to explore & make beating the level e’en easier, since it is s’posed to be a 1st-cycle level.

O’erworld

Since I don’t have much to say ’bout the level, maybe I could talk ’bout this, ’stead.

I haven’t programmed anything yet, but I have done some design:

As shown, the map cycles toward the center, cycling through the level themes: city, forest, mines … factory; city, forest mines … factory. I plan so far is that when you beat a level some event happens that allow you to proceed to the next — the most common being some solid tiles turning nonsolid.

There are still a few questions & problems I need to puzzle out. For 1, there’s the need to balance space: as the cycle goes farther in, the amount o’ space shrinks. That requires me to balance the inner cycle so it’s not too crowded gainst the outer cycle so it’s not too open. Already I think I’m having trouble with this since e’en with all the padding space used in the outermost cycle, I don’t think the city, forest, & mines sections go far ’nough. ( Remember, in all the levels in the 1st cycle must encompass the whole o’ the outer ring, since that’s where it transitions to the 2nd cycle. )

I’m still not sure if I want the level layout to be linear level-to-level. It seems ol’ fashioned & o’erly limited; but @ the same time, I do want to have some progression. 1 idea I had was to have “warp zones” in the form o’ secret exits in some levels that create paths farther down into the cycle.

Download sloppy source code

Posted in Boskeopolis Land, Programming

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 XIX

Cotton Candy Clouds

Based on the simple gimmick o’ appearing & disappearing cloud platforms, blatantly ripped off from Wario Land 3’s “Above the Clouds”. Oddly ’nough: I came up with this idea while working on ’nother level with a different gimmick, but decided to introduce it here. That other level should hopefully be done soon.

If anything, the bramble blocks took longer to make. Most o’ the graphics in this game were simply drawn pixel-by-pixel or simply used a photograph I fiddled with in GIMP. These are, I think, the 1st graphics I drew in high-resolution like actual illustrations & then fiddled with in GIMP so that it tiled correctly. They’re still wonky: there’s still some wonkiness with the tiling, & the block interaction’s still weird ( ne’er got round to making parts o’ them act like slopes ). It shouldn’t matter too much, since you won’t see most o’ the brambles for long as you’ll quickly die if you stay near them too long. ’Twas hard for me to look @ them for long e’en while trying.

This was also a case wherein metaprogramming helped, since manually creating all the json files for each o’ the dozens o’ blocks would’ve been tedious. Since the graphics & blocks match up, I could just make a simple Ruby script that generates & spits out JSON files. It also made it easier to make changes to many o’ the blocks quickly.

Originally, I wanted this level to end with 1 last quick burst o’ cloud platform hops, but with platforms that moved mo’ quickly; however, I couldn’t get a speed that was much quicker, but not so quick as to be ridiculous with how long Autumn’s jump too, & ’sides, I thought the level was going on a bit long ( I aim for half a minute, ’specially for an early level like this; this 1 takes a’least 40 seconds if speeding through ), so I snipped it.

Gem & Time Challenges

Something else I hastily ( & sloppily ) programmed in were gem & time challenges. As shown in the “Cotton Candy Clouds” video, holding X while on the level select screen shows the gem & time score challenges. If you beat the level with mo’ gems than the challenge or with a shorter time than the listed time, you get a checkmark next to the gem or time, respectively, & the respective score turns green. If you beat the level, get its diamond, & beat its 2 challenges, the whole level line becomes green, indicating that you’ve 100% it. I’ve already made scores for all the completed levels.

You’d be surprised by how difficult ’twas to get the time score on the 1st level, & how proud I am to have beaten it by 1 second. If only I had been recording or hadn’t turned off saving…

Speaking o’ %, as the bottom-right shows, there’s now a game %, divided by each level. For each level percent, beating it nets 50%, getting the diamond 30%, & beating each challenge nets 10%. Since the % use floating points & rounding, I don’t know if getting everything adds up to 100% precisely, nor could I check, since there’s a bunch o’ unfinished levels that are impossible to beat or get the diamond on. There’s also “Soupy Sewers”, which is impossible to 100%, since it requires an oxygen upgrade I still haven’t programmed in yet.

As a bonus, I made a video showing how to beat the time score in “Cotton Candy Clouds”:

I haven’t done so for the gem score, ’cause it’s too hard for me to bother ( you have to collect every gem in the level without dying ).

Download sloppy source code

Posted in Boskeopolis Land, Programming

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 XVIII

Minty Mines

There’s not much to say ’bout this level, since most o’ the effort when into drawing the graphics. In truth, I was just messing round & happened to finally get mine tiles & liked, & then was finally able to make a halfway decent background ( though I still wish I could figure out how to make good-looking wood or metal cross-bars, like you usually see in mine backgrounds ), so I finished this level idea I’d been fiddling with.

I still find the level feels awkward to play. The main problem is that Autumn’s momentum is strange when she bonks her head on the ceiling, which happens all the time here due to the cramped space & rarely anywhere else, since most other levels are wide open with no ceiling. I feel like Autumn’s horizontal momentum plummets when she bonks her head, & it just doesn’t feel right & causes me to have trouble avoiding enemies that otherwise are laughably easy to avoid. ¿Did Mario games control like that?

So let’s talk ’bout the rest o’ the game ’stead.

Much nothing

Unbelievably, I have had actually still been working on this project here & there since my last update — though not as oft as my manic episodes in December. It’s just that most o’ what I did turned out useless. Most o’ it was just experimenting with refactoring code so that ’twas less messy & janky. Mainly I tried redesigning the sprite code so that it wasn’t an unheavenly mess, ’specially the sprite states ( floating, on-ground, falling, jumping, & such ), since as o’ now most o’ that’s just a bunch o’ flags sitting in the sprite code, which isn’t e’en always consistent ( whether or not code checks for “is_jumping” or “prev_is_jumping” varies ). Due to the way the block components use polymorphism to interact with all sprites, the Sprite class used by all sprites also has many variables used by only a few sprites, which is wasteful. ’Course, there are many sprites that don’t jump @ all; but worse, there are many variables only used by the player, such as climbing code; but ’cause they’re manipulated by block component code that is run by all sprites ( & all have the same interface, due to polymorphism ), it can only manipulate things that the Sprite class has, since as far as it’s concerned, that’s what it gets a reference to, not any particular subclass. I found a much easier, though less elegant solution: simply have player-specific code in some singleton class, like Inventory or EventSystem. ( Though, now that I think ’bout it, that’d cause trouble if I e’er needed Dagny to be able to climb ).

I doubt any o’ this matters much, since wasted memory is probably the least o’ my efficiency problems, & it’s not as if I’ve had any slowdown. For instance, the fact that Sprites use polymorphism @ all, & thus must be held as pointers in the sprite vector rather than as contiguous full objects means that the sprite code probably has plenty o’ cache misses & such, which is probably far worse than the unlikely scenario o’ using too much memory.

Anyway, I was able to create some rather elegant code @ 1 point wherein, for example, the code for jumping was all divided into a separate class where it didn’t get in the way & only existed for a sprite if it actually used it. The problem is, in every alternate version I’ve made, the physics are off — ’specially the collision. & in the battle ’tween code that’s elegant & code that’s right, the code that’s right wins.

Thus, the current project still has the messy, inefficient sprite code.

An e’en worse problem than this not-serious programming issue was simply a designer’s block in terms o’ level design. Ironically, a task I thought would be easy is probably e’en harder than other ideas I had. This game is a simple platformer — so simple that the protagonist doesn’t e’en have an attack other than jumping on enemies. Making a simple platformer that has some creativity, does something new, is immensely difficult ’cause platformers are a well-worn genre. For instance, I try to think o’ interesting enemies to make, only to realize Mario has already done everything. Every idea I come up with, I hear Dougie chime in my head with his nasally voice, “¡Mario did it! ¡Mario did it!”

I’m also still trying to figure out what to do with the o’erworld map. My main idea is to have a Zelda-like game wherein passages lead to the platformer levels ’stead o’ Zelda dungeons, but I feel that may be too much. Mo’ importantly, the variety would be hard to get right. Zelda games usually have a rather limited set o’ themes for o’erworlds; the 1st Zelda game had, what, ¿rocky terrain, forests, a graveyard, rivers, & mountains? This o’erworld needs to have cities, forests, mines, snowy areas, icy areas, factories, deserts, a store, a Pac-Man maze, sewers… Also, the levels are designed like my spiral idea o’ cycling through themes rather than having themes for each “world”, which would only mesh weirdly for a Zeldalike o’erworld. ¿Would the player just go all round the whole o’erworld multiple times, somehow unlocking ’nother part o’ each area on each cycle?

Posted in Boskeopolis Land, Programming

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 XVII

I already did this months ago, only I just found out it for some reason didn’t publish when I wanted it to.

Value Valhalla

You can probably guess that this is a parody o’ Super Mario Bros. coin heavens.

You’d be surprised what a pain ’twas to not just loop repeatedly, but to add that extra part after the 3rd loop with the diamond.

But fans o’ Pannekoek2012 will be excited ’bout one way it’s implemented — yes, that’s right: it involved parallel universes. No, this wasn’t as an intentional joke or reference; I actually experimented with having your character’s & the cloud’s positions revert back to the other edge, but couldn’t get it to work smoothly.

Thus, the way the loop actually works is that while you & the cloud you’re on keeps gaining X position, the Map class manipulates the rest o’ the level to give the illusion that it’s looping. The camera is changed so that it no longer stops @ the width o’ the map, but goes on fore’er, & the map code for giving block indexes to the block system changes so that it gives one relative to how it calculates what the left edge o’ the particular “current loop”, which is calculated based on the player’s position, rather than outputting invalid indices past the edge o’ the level. ( As a note, recall that I mentioned in the last post how the cart level required the horizontal edges o’ the screen to be even to making the cart not bump into blocks from 1 edge while on the other edge. I fixed that now. )

The sprites also had to be repositioned ( ‘cept for the main cloud platform sprite: it does loop back round if you let it go past the edge o’ the screen; but due to nuances for how it works, it has its own separate code for looping ). Said repositioning code only works if the sprites reset to their original position, for some reason. Luckily, the bees automatically do that, anyway, & the cloud block sprites can do so without any problem. ( Note: not only are the bouncy blocks sprites; so are the flat ones, to make it so their eyes follow you. Yes, I created extra work for myself just so I could make blocks watch your character. )

I should point out that this level theoretically works fine looping in the other direction, too ( though the diamond part’s only programmed to appear on the 3rd loop going rightward, e’en if going leftward from the 4th loop ). In the original version o’ this level, there was a 2nd cloud up top that went leftward. However, I felt it ruined the gimmick o’ this level, since it made looping horizontally unnecessary, since one could just go back & forth. Plus, it wasn’t all the useful, since you can reach close to the top already. Lastly, changing it to work with the extra diamond area made it impossible to keep the cloud platforms in sync. This impressive feat was the only reason I cared ’bout keeping the other cloud, & since it’s now gone, I see no reason to still want the cloud platform. I think the level works much better now.

Levels to come: a sewer level influenced by “Wet-Dry World” & a sky level where you’re a flying owl.

Download source code.

Believe it or not, I’m still working on this — just not doing anything productive or worthy showing.

Posted in Boskeopolis Land, Programming

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 XVI

Mart Cart Madness:

This was a level I’ve been sitting on for a while, & I finally got round to finishing it — which mainly meant drawing all the graphics.

I still worry that the level may be unfair. I make it look easy in the video; but I’ve played this level a’least 100 times as I tested it, ‘specially recently, & wary-eyed viewers should be able to spot that I’m jumping before any fresh player should know what’s coming. In truth, I just have this level burned into my memory & was just jumping on pure muscle memory.

The problem is, your character goes so fast & the level’s still so cramped that you have to be tight with your timing. It’s very easy to nick a wall with your very edge down in the warehouse area near the start. But I don’t want to slow your character down, & adding extra space would require me to significantly redo much o’ the level, since I’d have to push the rest o’ it back.

That said, it’s not too much o’ a problem: dying is just a snap o’ a rubber band: you lose 2,500₧ in a level that nets you o’er 10,000 on a single victory, & the level’s short. This is why I wanted you to go fast: auto-moving levels are boring as boards when they take too long & go so slowly. You know you screwed up when the player is holding the forward button futilely trying to speed things up. I can a’least say that I doubt a player would do so in this level.

Interestingly, the warehouse part near the end has much mo’ room for error: thanks to the walls being all springs, you don’t lose any health or die from the vast majority o’ errors, allowing for unlimited errors. This probably could’ve worked better earlier in the level; then ‘gain, maybe it’s better to have such a parachute near the end, when you’ve got mo’ to lose. I do like the calmness o’ this section.

Beating the level is simply the player cart sprite checking if the player has gone past the right side o’ the level, which could probably be exploited somehow. Due to a quirk o’ how maps are laid out, I had to align the end with a space on the far left side o’ that Y position so the player wouldn’t bump into anything on the left. Similarly, to make the cart start past the left side o’ the level, I had to put empty space on the far right o’ the starting Y-position, which is luckily just a large clump o’ solid blocks that should ne’er be seen by the player in-game. If you look @ the map in Tiled ( in the Github project: resources/maps/land-shop-1.json ), you can see the seemingly arbitrary down near the lower-right.

The way the player’s cart sprite works is simple: it just checks if it has a horizontal direction & automatically moves in that direction. The springs change your sprite’s direction. The upward springs down in the 1st warehouse area nullifies your cart’s horizontal direction & ‘stead sets your cart’s vertical direction to “UP”. With that, your cart automatically moves upward till it reaches a hard-coded Y-position, & then nullifies its vertical direction & sets its horizontal direction to “RIGHT”. It’s not friendly for reuse in other levels, but I don’t plan to make ‘nother cart level. Remember the wise words o’ Programmer TV Tropes ( ¿Computer Tropes? ): YAGNI. The sprite also checks if you collide with anything to the side or ‘bove & damages you if so. Springs aren’t solid, so they don’t count as collisions.

Palette changes are simply done by placing graphics-less blocks in select spots, which activate when onscreen.

The next level will probably be a sky level I’ve been working on for a while…

Posted in Boskeopolis Land, Programming