Ghosty Jumper - A Difficult Platformer

Source file here: https://github.com/TheProgrammer163/ArduboyPlatformer

I made this apparently 10 months ago according to when I last updated the files on GitHub.

There’s only one level for now and it is extremely difficult, took me 45 minutes to beat the first time.

Controls:
Left and Right DPad buttons to move.
One button to jump.
The other button to sprint and jump higher <- very important. Hold it as you move to run faster. You jump higher only once you’ve reached maximum speed.

The goal is to reach the end, the game will let you know once you’ve won.
There is currently no timer, if you want to know how long it took you to win, set up a watch or timer for now.

I was supposed to update it so that each tile uses only one bit, so that it could have about 30 levels but I never got around to it so for now, there’s only one very difficult level.

I’d love to make a .hex or .arduboy file for it eventually, but for now it can be compiled from source.

Big thanks to Pharap for his fixed point library, the player movement never would have been this smooth without it. Another big thanks for his infinite patience helping me learn just enough C++ to do this (and hopefully more game or updates to this game when I get the time and patience for it). Other people helped me as well but unfortunately I don’t remember all the names.

11 Likes

Nice! But without some kind of checkpoint system, I think I would not be able to play this without rage quitting lol

5 Likes

Beautiful!! :slight_smile: Nice release. I think there’s a few things that you could add that really make this game interesting. Maybe instead of a checkpoint system, you could do a Prince of Persia-style thing where when you die, time rewinds.

1 Like

I think I vaguely recognise this code. :P

When you have the time and/or motivation to work on this again I can think of a few suggestions.

1 Like

EDIT: for some reason the quote didn’t work, but this was as a reply to you @Vampirics about the difficulty

This was originally a prototype level that I made in 10 minutes for testing, normally you’d be able to beat it once you’d reach this level.

With more levels, I could start by implicitly teaching all the important mechanics. I did it with one thing in this level; the wall jump. The first wall jump doesn’t kill you when you fail, you just have to try again. But at the very end of the level, there’s one that if you fail, you start over. The first one is to make sure that you can beat the one at the end

Normally I’d introduce harder and harder obstacles through the game first in a non deadly way, and once you’d reach this level, you’d be able to beat every single one of them :D The second time I beat it, it took me 5 minutes (right after I beat it in 45 minutes). I made the video of the game much more recently, but I was able to beat it quickly enough compared to my first try.

Another solution is to have different paths, and some that are riskier but faster. An example is this non obligatory wall jump path: https://youtu.be/xE4XyodZMM0?t=26

I’m open to suggestions @Pharap and @crait, there’s a few things that have been on my mental to-do list for a long time, which is why I hadn’t yet “released” it.

  1. An actual timer, for now all you get at the end is a nice victory message.
  2. Saving the time to eeprom, so that you know what you have to beat (you’d see your high score at the beginning maybe)
  3. A ton more levels. everything that is neither air nor solid, is actually hardcoded in some functions. Each column of the level would only require 1 byte (8 bits). The levels are 9 tile high, but one row is actually a duplicate. I could either have about 30 levels if I only use these two tiles, or around 15 if I use 4 tiles. More levels would allow a nice difficulty progression, and also an actual reward for beating a level; you’d unlock the next one.
  4. I might modify how long you need to hold the sprint to be able to jump higher, because it’s difficult to not fall off when trying to get enough distance to do the hardest jumps.

I have a PC version of this by the way, with a crappy built in level editor, but if I modified it a bit I could make it spit out the level data. Being able to edit a level in real time is very useful for testing. I was able to test what jumps were feasible and which ones weren’t, and it allowed me to make this level in 10 minutes just by knowing which jumps wouldn’t be possible.

I have some free time this week and in the next few weeks, so I’m open to improving it soon

3 Likes

Most of my immediate suggestions would mainly be code improvements.

  • Replace the const member variables in Player with static constexpr member variables
    • non-static const member variables technically aren’t proper constants - they consume RAM because they’re technically part of the class
  • Move some of the helper functions out of the player class and into a separate header
    • E.g. velSign and velClamp would make more sense as generic sign and clamp functions.
  • Change any ‘all caps’ constexpr variables to camel case (or pascal case). (Using ‘all caps’ for non-macros goes against the isocpp guidelines.)
  • Maybe introduce actual Point and Vector classes to simplify the code
  • Remove any ‘dead’ variables and code (e.g. Player::testForBug)
  • Get rid of implicit casts from bool to uint8_t
  • I can see a few opportunities for optimisation here and there

You might want to change that.

Although having only ‘air’ and ‘solid’ makes level compression easier,
hardcoding stuff is rarely a good idea because it limits flexibility and there will almost always come a point where it ends up being a roadblock.
(I.e. when you want to implement something you hadn’t planned for and you suddenly realise your hardcoded parameters are working against you.)

Depending on what exactly is hardcoded there will probably be other options available for how to handle it without making levels too much larger.
E.g. if it’s just a case of where the ‘start’ and ‘end’ of a level are, those can be stored as coordinates without too much overhead.
If it’s something more complicated you might be able to read the level into RAM a piece (e.g. column, chunk) at a time and do some post-processing - essentially ‘decompressing’ the level at runtime.

1 Like

Very late reply here on my part, but I wanted to let you know I’ve finally taken your advice of starting to learn to use SDL2 with C++ :D

I may or may not update my Arduboy platformer as well, since I’ll be diving deeper into C++ anyway. Thanks yet again for all your help regarding C++ and the Arduboy by the way

1 Like

If you ever need any advice or information about general C++ and/or SDL2 then feel free to PM me.
(I know how to wrap the pointers in std::shared_ptr so you don’t have to worry about deleting/freeing things.)

Also if you’re using Visual Studio then give my project template a go.

Why a project template?

I used to always manually edit the compiler settings when making an SDL2 project,
but one day I sat down and figured out how to make a template,
and then I published it so everyone else could experience the joy of not having to manually mess around with the compiler settings.

1 Like