My current project-time black hole: I'm building a video game!

I generally have only a limited amount of time each day to devote to projects that don’t directly relate to life-maintenance or my job. Lately, my job has been eating up a slightly higher than usual amount of time, and I’ve developed a new goal for the new year: to create and release a video game.

Yeah. I know.

However, even if I fail at it, I’m building this game in Java, which I’ve never programmed in before. So, regardless of anything else, I’m learning a good deal, at least.

I figured I would start writing a bit about my experience designing and programming a game, and describe my roadmap and to-do list, so as to keep the blog active and still feel like I’m doing something toward the end of completing this game. Join me below the fold, if you’re interested!

Several months ago, I discovered the procedurally-generated platform game Spelunky. I discussed it with a co-worker, and mused on how difficult it might be to build a randomly generated platform game that is still traversable.

I have long had a fascination with procedurally-generated video game content (see my love letter to the roguelike, or my SSA filler post about Shiren The Wanderer). By “procedurally generated”, I mean the game environment isn’t actually designed, per se, so much as built by a random number generator and a series of rules. Games like Diablo feature this heavily — every playthrough, you’re running around in different dungeons built out of hand-crafted setpieces that you might see dozens of times during the run of a game, stitched together to make each level relatively novel. The monsters you fight will be somewhat randomly generated — or at least, randomly chosen from a list of designed monsters. That is procedural generation — random content that isn’t completely random, but random within certain constraints.

I guess part of the reason I like roguelikes or other procedurally-generated video games is that I normally have a drive to complete games at as close to 100% as possible, and just knowing that it’s literally impossible to complete infinite dungeons helps curb that drive.

So Spelunky with its randomly generated platform engine gave me an idea. There are a few other sorts of games that I absolutely love, like retraversal platformers, but lament that they’re so short and have such limited replay value — like the Metroid games, the Castlevania games for the DS, or even the venerable Castlevania: Symphony of the Night. But those maps that are created for those games have certain elements about them that could theoretically be reproduced by some very clever random generation. And with random generation, I could enjoy this sort of game whenever I want, at the scale I want — a small dungeon, or a big dungeon, or anything in between.

I decided to pick up Java, libgdx as my rendering engine, and do something I’d taken a few stabs at in the past — building an honest to goodness video game. I had a concept, so I decided to see if I could build a proof of concept.

A randomly generated Castlevania-alike would require a procedurally generated dungeon. There would have to be clear area delineation, with retraversal to get to other areas and rewards, a general progression in difficulty curve commensurate with the experience and levelling and gear granted, and secrets galore.

So I built a dungeon map generator. I’d say that short of a few rough edges, or attempting to build something even more absurdly complicated like shaping dungeons to be less radial from the point of creation, this map generator is pretty much complete. I built a map screen that probably won’t represent the real end result map screen, mostly just to visualize my random map generation as I progressed. Here’s a pic of its current state:

A generated map for my platform game. Areas are defined by different colors, special rooms are designated with colored squares, and special doors and breakable walls are indicated by boxes on room borders.
A generated map for my platform game. Areas are defined by different colors, special rooms are designated with colored squares, and special doors and breakable walls are indicated by boxes on room borders.

I’ll perhaps do a post up at some point explaining what all of this is about. There are save rooms (green/black), transporter rooms (pink), boss rooms (black/yellow), locked doors (color-coded to the key level required), and an end boss in a 2×2 square area. You start in a 1×2 room attached to the right edge of the screen (on generation, this first room will randomly attach to the left or right edge).

Some more factors to take into account are that there would have to be something like permadeath, to give you a real challenge in fighting your way through dungeons, while still ensuring that the players feel a measure of progress through a game. And there should probably be a hub-world, or village, something like the village in Chocobo’s Dungeon or Castlevania: Order of Ecclesia, with helpful characters being unlocked as you complete each dungeon and defeat each major boss.

But I suppose to get any of that, first you’ll need an actual platform game engine. And I have a pretty good start in on that too.

A demo of my test room, with my character jumping to the right
A demo of my test room, with my character jumping to the right

This is not randomly generated yet, but I figured out how to start creating a TiledMap resource that this game engine can read, so at some point I’m going to start building those randomly generated rooms. For now, I’m in a bit of a testing jungle gym that I’m loading from disk.

So far, I have collision detection on flat surfaces working properly. Collision detection kinda sorta works on 45-degree angle tiles, but needs a good bit of work to make presentable. Gravity works, and jumping works. The character goes into a special fast-fall animation when falling too far, and will land hard with a three-point landing state after hitting the ground from that state. My animation engine is adapted from the default libgdx to allow for more complex animations with display-times per frame, so I’ve actually gone significantly beyond the game engine I’ve chosen. The tileset is something I took an hour to whip up, and isn’t likely even the final game size — it’s 32×32 now, but I might change it to either 16×16 or 24×24. And the background is just something I grabbed from OpenGameArt.

I started originally roughing in the game using sprites ripped from Castlevania: Order of Ecclesia (Shanoa is an incredibly detailed sprite — her standing animation alone is ten frames!), but decided to rip it all out and use Poser to rough-in my animations until either I get around to doing the pixel art for it myself, or possibly attracting / hiring a pixel artist to do the art for it properly. You can tell that I’ve only just ripped it out at this point in the dev, because the bounding box around the jump animation is still keyed to Shanoa’s jump frame dimensions. Remind me to go edit that, self.

I actually have most of a plot in mind for the game, too. It will involve mythology, mostly Japanese mythology for the main plot but with a whole hell of a lot of every other mythology for bosses and minibosses and enemies. It will involve skepticism and atheism, because I just can’t help myself. It will feature a female protagonist in the role of generalized, omnitalented badass, because every other game in the world is apparently incapable of letting you be a female protag without also making her somehow stand out from the “default” of male, or throwing her into a dungeon to be rescued or a refridgerator to be plot motivation, or hiding her behind a really expensive goal on the project’s Kickstarter page. It will have cutscenes, and it will have an actual backstory for the protagonist. And I’m also debating whether or not to include non-game-engine puzzles, something like Fez’ or Commander Keen’s alien alphabets or button input puzzles. Something that you might notice and wonder about, but not have it occur to you that it means something special and that you should probably try to figure out, which would enrich the game.

But I’ll spare you all that for now. Perhaps that’ll be another post!

This poor game doesn’t even have a name yet, much less a name for the protagonist. I have half her backstory and the plot of the game fleshed out in my brainmeats, but I don’t have any names for the most important parts of this game yet. I gotta get on that.

Meanwhile, two roguelike platform games have already come into existence: Chasm and Rogue Legacy. This suggests to me that either I make this game now, or never.

{advertisement}
My current project-time black hole: I'm building a video game!
{advertisement}

11 thoughts on “My current project-time black hole: I'm building a video game!

  1. tso
    1

    Your generator looks nice. I never have a good time with those.

    Man I should have backed chasm. Totally forgot and looks way better than rogue legacy ended up being IMO.

    I’ve been working a bit myself on a randomly (more Zelda dungeons than anything generated action game. Also started around faith issues but now has more of a warring gods angle going on… You really like castlevania so I guess baddies going off on long I’ve got you now bond tangents works a bit better and you could be more explicit. Non engine puzzles would a good place to mechanically reinforce themes too. Misinterpreted graffiti etc.

    But I’ll shove off now, its late for rants.

  2. 2

    My money maker time waster project is microcontroller code for secure infrastructure. This project uses ARM Cortex-M4 microcontrollers running my own RTOS. Commands sent via WiFi or other insecure channels can not be faked. I use public key cryptography and AES256.

    Each microcontroller generates its own key pair. The private key never leaves the microcontroller. The microcontrollers know the public key of the master station. Then with the Diffie–Hellman key exchange and the exchange of some randomness both the master station and the remote microcontroller produce the same keying data for AES. A time stamp foils replay attacks.

    The host side is in Java. I wish Java had unsigned ints, but I’m sure that others had this wish first.

    Thus some hacker in China or or that matter, Fort Meade, MD, can not open the sewage outlet gate to the river or other nefarious act.

    Now all I gotta do is find an interested party and collect some much appreciated cash.

  3. 3

    tso: You should check out Binding of Isaac. It’s sorta like a combination of a shooter and a roguelike Zelda 1 game. Plus it’s got heavy religious themes, as well as a lot of internet memes. And a lot of scatology to go with the eschatology.

  4. 4

    Peter: well then. That does sound interesting. I assume the proof of concept is done entirely software? I’d be wary mostly of how the hardware deals with buffer overruns and more traditional DOS than cracking the AES key. AES256 is damned good.

  5. 5

    Wow, I feel lame in comparison, Jason. The only thing I’ve been doing lately is converting barley, hops, and water into beer, then converting it back into water again. Making a video game? I’m jealous. The last truly nerdy thing I’ve ever done is create my own pen & paper RPG, and that was 20 years ago now.

    On topic: I have practically no useful programming or artistic talents, but I could playtest for you if you need.

  6. 6

    >I assume the proof of concept is done entirely software?

    Yes.

    I’m using ECC (Elliptic Curve Cryptography) with NIST p-256. Low level code like multiplication of two 256-bit values (8 32-bit words) then modulo the prime all done in assembly. Addition %prime and right shift one bit also done in assembly. High level ECC algorithm stuff found on the ‘net were rewritten in C++ using my low level code. Much point passing using reference. At 168 MHz my code takes ~35 milliseconds for a point multiply.

    I intended to say more but this thread is about your current project, not mine.

  7. 8

    Ooooh. I have always had a good deal of reverence for people who can program in assembly, because I’ll be damned if I could do anything other than maybe, MAYBE alter an existing mov pointer in someone else’s code. And even that, with tutorials. I’m higher-level languages all the way.

    I’m looking forward to this becoming commercially available, even if too expensive to use to control an arduino-linked coffee maker over the net.

  8. 9

    Your description sounds very much like a more ambitious version of Rogue Legacy. (Which I’ve really liked and still play.) I.e., Rogue Legacy with a greater degree of retraversal. (RL involves beating just four bosses to open a door you pass at the start of the dungeon. Finding and unlocking classes, abilities and stat increases are the gates to deeper dungeon exploration. They aren’t doing metroid-vania style gating that requires boss kills to explore.)

    Try it if you haven’t, it might give you some inspiration or clarify your implementation in light of the choices made by others doing similar games.

  9. 10

    “Ooooh. I have always had a good deal of reverence for people who can program in assembly” – It’s really not that difficult. It’s just fiddling with a very limited set of variables (“registers”), and knowing the hardware (which is more difficult than the assembly itself). If you don’t mind me asking, what age are you (since not knowing assembly usually means “young” :)).

  10. 11

    >[Programming in assembly is] really not that difficult. It’s just fiddling with a very limited set of … registers.

    Attention to the details of the specific hardware is important. The project I described is ARM Cortex-M4 based. (Although -M3 processors would work just as well.)

    On ARM machines subroutine calls differ from unconditional branches in that they store the return address in r14, the link register. That register is an otherwise completely normal register. On many machines (modern Intel parts, Motorola 68K, DEC PDP-11) the return address is pushed on the stack. On the two processors in the CDC 6000 series mainframes calls stored the return address into the subroutine address. On Microchip PIC machines there is a return stack that for most purposes is only usable for returning from subroutines. On the (Memorex version of) the IBM 3350 Storage Control Unit subroutine return addresses were stored in r2:r3 of the currently selected register set.

    But that’s not were attention to detail comes in. These machines are programmed to do useful work. That’s were attention to detail comes in. On the Storage Control Unit I had to read data from the moving disk one byte at a time comparing it to a 4-byte pattern and note if and where it differed from the desired pattern. Then save that difference in a buffer for later analysis. The problem: I had just over 3 instruction times per byte. Making it all possible was that most insurrections did multiple things and that I could go 5 instructions between bytes if I got back to the fast loop quickly. I spent half a day designing that read loop. The entire project depended on that loop working. Even thinking of Java or even C was WAY out of the question.

    >… and knowing the hardware (which is more difficult than the assembly itself).

    For difficulties focus on the built in peripherals. On the STM32 Cortex-M4 parts setting up the internal clocks starts with
    -what processor instruction rate is desired
    -what clock speed should feed the internal peripherals
    (several clock busses)
    (some settings are to fast for some peripherals)
    -which of several oscillators are to be used
    -setting the phase lock loops (note the plural) properly
    GPIO pins have to be repurposed for little things like analog inputs or USB. The Reference Manual is 1416 pages. Learning how to read the damn thing is an art unto itself.

    The easy coding part of my ARM project was multiplying a pair of 8-word multiplicands into one 16-word product. (256 bits times 256 bits makes a 512-bit product.) Because the computational hardware could multiply 2 32-bit registers into a 64-bit product I only needed 64 multiplies and a mess of addition to put it all together. Making it fast made it interesting.

    >If you don’t mind me asking, what age are you (since not knowing assembly usually means “young” :)).

    I am to old to die young. I qualified for Social Security and Medicare less than 10 years ago. If I start to approach the Pearly Gates, River Styx or Nirvana, Medicare and Kaiser will try to delay the inevitable.

Comments are closed.