Steve Johnson

LD 38

Rogue Basement post-compo build: FoV, bug fixes

Rogue Basement now has field-of-view! You only see monsters within your line of sight, and you retain a memory of the basement layout.

Get it on itch.io

Also:

  • Log messages are much less confusing.
  • Rocks can no longer be thrown into walls.
  • Monsters no longer pick up gold. It's all for you!

Screenshot 2017-05-06 18.27.03.png

Rogue Basement annotated source code

I took the time to extensively comment my entire game. I ended up with 885 lines of comments (wrapped at 80 characters!) for 1,570 lines of code. The code is pretty good for a 48-hour game and might give you a starting point for writing your own roguelike.

Topics covered:

  • Python 3 in general
  • Scene management
  • Efficient drawing with BearLibTerminal
  • Level generator with BSP trees
  • Strategies for storing and using data
  • Flexible system for simulation and AI
  • Using pyglet for music and not graphics
  • FoV using recursive shadowcasting via clubsandwich (post-compo)

Screenshot 2017-05-14 21.16.30.png

Rogue Basement score commentary

Everybody's doing these, and even though no one cares about me, I'm doing one too. :-)

Screenshot 2017-04-23 19.08.35.png

When getting scored, I'm most interested in seeing if the balance of my effort was well-spent. On one level, a game either works or it doesn't; in 48 hours, you get on a path early and it's hard to get off it if something isn't working, and that's at least 50% luck no matter how good you are! So ultimately, scores are most useful as measuring sticks of your relative effort in each category, rather than as a global rank.

Here's my commentary for Rogue Basement. (Compo game, so rank and percentile are out of 549 games with scores.)

Category | Rank | Percentile | Score | # ratings ---------- | ---- | ---------- | ----- | --------- Overall | 135 | 75.4 | 3.667 | 47 Fun | 179 | 67.4 | 3.409 | 46 Innovation | 379 | 31.0 | 2.841 | 46 Theme | 398 | 25.5 | 2.977 | 46 Graphics | 374 | 31.9 | 2.932 | 46 Audio | 24 | 95.7 | 4.000 | 44 Humor | 157 | 71.5 | 3.000 | 42 Mood | 94 | 82.9 | 3.659 | 43

Overall: 135 / 3.667

Not top 100, but about what I was hoping for. I made sure to make something "finished" and put thought into every category.

Fun: 179 / 3.409

I've got some real mechanics and good loops, so from an academic game design perspective I call it a success, but other games are definitely more fun than mine.

Innovation: 379 / 2.841

I made a very by-the-book roguelike with some very minor innovations. Frankly I'm surprised this isn't lower.

It's my lowest score but not my lowest rank, so I'm guessing the innovation category skews low in general for Ludum Dare.

My last LD entry (LD26, We Dreamers) got 6th overall in innovation, so I know I can do this category well! I just chose not to this time.

Theme: 398 / 2.977

My lowest rank but not my lowest score. I will admit to not worrying too much about the theme, because (a) it wasn't a great theme, and (b) themes are really just for inspiration anyway. Going into the compo, I knew I was going to make some kind of roguelike, because that was just what I was in the mood for, and the theme was just a framing device for that.

Graphics: 374 / 2.932

I don't care at all what I got in this category. I've always hated worrying about graphics for LD. Seriously, this is what I did last time. So players will either say "you did ASCII pretty well" in the 3-4 range, or "ASCII sucks" in the 1-2 range.

Audio: 24 / 4.000

WOO WOO OH YEAAAAAAH

The audio for this game is a 15-minute original soundtrack I wrote between midnight and 1:30am the second night of the compo. I guess people liked it!

I'll be putting more thought and energy into audio for my next LD game. It looks like this can be my superpower.

Humor: 157 / 3.000

Humor in my games has always been about covering for a lack of content or unbelievable set of mechanics. "I only have one level for my roguelike. Why? Because...oh, it's some idiot wizard's basement." I am pleased that people liked that aspect of it, but I put in essentially no effort.

Some of the humor scores might have been because it's possible to punch flying rocks out of the air, and some of the flavor text is not correct English...

Mood: 94 / 3.659

I would attribute this good score to music, consistent decent ASCII feel, and title screen art. I've always thought of this category as "how much does this game feel like the game it is trying to be?" and on that axis I was happy with how Rogue Basement turned out.

LD 39

Any artists want to make a small roguelike tile set for the jam?

PoweRL is a pocket-sized roguelike about not running out of power before the end of the game, and also shooting things. It needs about ten simple sprites and some UI love. I've already got a soundtrack and nice non-bfxr sound effects, so you'll be part of something relatively polished.

I'm putting it in the compo with the Unicode graphics, but a jam version would be great.

This game will be Mac and iOS only.

If that appeals to you, get in touch! steve@steveasleep.com

Screenshot 2017-07-29 22.03.28.png

PoweRL postmortem

Title: PoweRL postmortem Category: Articles Slug: powerl-postmortem Tags: games Status: published

Ludum Dare 39 fell on a weekend when I wasn't busy, and I wanted an excuse to learn a bit about Apple's game libraries, so I made another roguelike, PoweRL:

screenshot.png

I wasn't in the mood for stress, so I set my standards very, very low. Ironically, the result is more commercially viable than most of what I make! That might not be apparent from the screenshot, but maybe this new version with updated art will convince you:

screenshot2.png

Swift, SpriteKit, and GameplayKit

"iOS engineer" is part of my normal job description, but in the past I've avoided using Swift or Objective-C for jams because it isn't cross-platform. But since I didn't really care about the outcome of this jam, I let my curiosity about SpriteKit and GameplayKit win out over portability.

I'm really glad I did, because after learning the frameworks, I spent almost no time worrying about the engine! My last Ludum Dare game, Rogue Basement, needed a lot of up-front work on the engine to get running, and then optimization work after completion. But with PoweRL, SpriteKit made for an efficient renderer and animation system, and GameplayKit gave me structure for gameplay code and a few nice utilities like pathfinding.

Iteration

Swift is a great language for iteration. In a lot of ways you can treat it like a dynamically typed language, but still have a lot of problems caught by the compiler. Even though there's a compilation step between writing the code and testing it, I think I iterated more quickly than I do with Python because I never hit a typo at runtime.

GameplayKit's entity-component system is well designed and honestly taught me for the first time how that kind of architecture is supposed to work.

SpriteKit's SKLabelNode let me write almost the whole game in old-school roguelike style, with letters representing everything instead of graphics. But at the end, it was very easy to swap in bitmap art.

Evolution of the design

Ever since starting to play 868-HACK on my phone, I've wanted to try making a game in the same genre (pocket roguelike). The SpriteKit template in Xcode immediately gives you a codebase that runs on macOS, iOS, and tvOS, so right from the start, I kept in mind a control scheme that could work on keyboards and touch screens alike. Swiping would move your character, and tapping would do something else.

The theme of the jam was "running out of power," so I did something dumb and obvious: I made a robot with a power meter. I put it in a level filled with walls, batteries, and "power drains." When I went to bed Friday night, that was it: a game about getting from Point A to Point B without running out of power, over and over again.

That's an interesting set of mechanics by itself because the player already has interesting decisions to make:

  • What path should I take through the level to minimize power loss?
  • Should I pick up all the batteries? Is that worthwhile?

The next day I added the butterfly, which moves one tile diagonally per turn. I added a health bar and some health pickups. Then I added a turtle, which moves one tile non-diagonally every other turn. Over lunch, I pondered other enemies I could add, and ultimately plopped in a literal chess knight.

These changes added a second dimension to the gameplay, which introduces new questions and tradeoffs. Players must now constantly decide whether they value power or health more, and act accordingly. They would be asking questions like this:

  • Should I pick up the battery, even if enemies drain my health along the way?
  • Can I make it through that pack of enemies?
  • Should I run through that line of power drains, or make it past those enemies? Do I value health or power more right now?
  • If I beeline for the exit, will I be able to recover the power in the next level, which is more difficult?

The enemies seemed to be able to get the best of the player too often, so I finally made use of the tap control: bullets! I added ammo pickups and a simple Bresenham line-based instakill shooting mechanic.

This change added an element of long-term strategy. Players could pick different values for these strategy-axes:

  • Never pick up bullets to avoid wasting energy, or pick up all the bullets?
  • Shoot everything on sight, or only shoot in dire situations?
  • Use ammo early, or hoard for later?

With all the mechanics in place, I played through a few times for balance. I tweaked the level generator parameters for number of enemies, amount of health/ammo/batteries per level, number of walls, and movement cost. The game got too hard after level 8, so I added a win condition at level 8. And that was it!

Influences

Two things influenced my approach toward designing this game. The first is Jesse Schell's book The Art of Game Design: A Book of Lenses. It helps frame a lot of important questions. The second is roguelikes in general, which at their core are about creating interesting decisions for players every single turn of every game.

Music

I spent an hour or so in Logic Pro with my 25-key MIDI controller, electric bass, and the Logic Pro Auto-Drummer. I started with the beat, added some bass, added some synths, wrote a new part with the bass, filled in with synths, and then shuffled it all around until it felt passable.

That's my normal way of working when I have limited time for music. For Rogue Basement, my last game, I wrote two songs just by holding down a single note for 5 minutes in an arpeggiating synthesizer and adding some occasional notes on a pad synth on top of it. Another Rogue Basement song was just a piano improvisation jam. When you only have 48 hours to make a game, you have to take as many shortcuts as you can get away with!

Art

I used Apple's beautiful emojis for enemies during development, but I felt that it wouldn't be in the spirit of Ludum Dare to use them as my final sprites, since they are finely rendered illustrations that I did not create. So I vector-traced them by hand in Pixelmator, added bad gradients, and called it a day, finishing about 20 minutes before the deadline.

Those sprites are fine in that you can tell what's what, but I really dislike the aesthetic. Over the following few week nights, I redid all the sprites in 16x16 pixel art. It's more of an explicit 868-HACK ripoff with that style, but it's also the only style I can use myself to create art I'm happy with. I bet that's true of a lot of programmers.

I can't use the new sprites in the Ludum Dare judging, but I can at least use it as the canonical version when judging is over, and recover a bit of self-respect.

Parting thoughts

I took a lot more breaks this time than I did in the past. These days I value my weekend chill-out a lot. But by being smart about tools, game design, and assets, I ended up with something I'm proud of.

For the next Ludum Dare, I'm going to try to join a team.

Some work I'm doing on PoweRL

I'm polishing Power-Q (called PoweRL in LD39) for a real iOS and Mac release. I made some endgame screens today:

Screenshot 2017-08-13 13.55.28.png

Screenshot 2017-08-13 14.52.06.png

Screenshot 2017-08-13 14.32.58.png

LD 40

A deranged game idea that is yours for free

You're an office worker. One day in a stupid team building exercise, your coworker friend wins a big-haired troll doll. He gives it to you. This would be OK for some people, except you have 2 problems:

  1. You have a severe phobia of troll dolls
  2. You have intense social anxiety and you are incapable of returning the gift

But now your other coworkers have noticed your troll doll, and it isn't too long before someone brings you another one. And because of your anxiety, you can't get rid of this one either! Soon, it becomes common practice to gift you trolls for Christmas, birthdays, and other random times.

The more trolls you have, the less you are able to do work. Something has to be done or you will go completely insane and you will be fired!

So you have to find creative ways to get rid of the trolls without your coworkers noticing and getting mad at you for throwing away their gifts.

(Obviously I thought about this a lot but ended up not going with it because I couldn't figure out a mechanic for getting rid of troll dolls.)

Honest rating lifehack

If you know your game won't be rated well anyway, there's no need to comment anonymously!

hashtag pro moves