A 7-Day Roguelike by Ross Andrews
I decided, pretty much on a whim, to do the 7DRL this year. I was planning on
writing an RL anyway, so this just gives me a timeline.
RBCL is going to be a fairly minimal RL: randomly-generated levels, simple
monster AI (walk toward the player, basically), no shops or town or anything. A
few potions / scrolls for spells, and you go down as far as you can. Your score
will be the amount of gold you find, plus points for equipment, plus like 10,000
for each level beyond the first you see.
Implementation: I'm doing it in Love2D, because I already know that really well,
and I'll use free graphics from "Tile Crusader" (found it on /r/gameassets).
Schedule: I don't have a *huge* amount of time to devote to it, I can't take the
week off work or anything. So I'm hoping to get a lot done this weekend and then
work on it every night next week.
- After Saturday I hope to have a guy, walking around the screen, with it
scrolling as he moves, and a sidebar with his stats / whatever.
- Sunday I devote to level generation and graphical fanciness (corner tiles for
- Mon..Wed: enemies and fighting them.
- Thurs..Fri: chests / potions / scrolls.
That's my bare-minimum schedule. If I start to miss those goals I'll start to
scale back, or declare the whole thing failed.
Starting development! I'm starting with the skeleton Love2D project I use, with
middleclass, LoveFrames, inspect, and a bunch of little classes I wrote (Point,
Map, List, Set, Tween, Promise, and Clock).
The first question I'm dealing with is what size to make the window. I've
settled on 1000 x 600. I want the map area to be a multiple of 40 pixels in each
direction, because that's how big the graphics tiles I'm using are. This lets me
have a 200 pixel status sidebar and the other 80% of the width as the map.
The only problem is that makes the height 15 tiles and the width 20, which means
I can't center the player on the screen because both dimensions would have to be
odd. I'll solve that by centering them horizontally anyway, and drawing two
columns of half-tiles.
Okay, this has been going easier than I expected. I've got a guy walking around
the map, he can't walk through walls, and the map is being drawn with graphics.
I'm going to start the status bar next, which means it's time for some actual
game design: I need to know what statuses to put on it.
We'll need health obviously, and what level you're on, and your current score. I
also want some kind of inventory or something, and a button you can click to
bring up a help screen. Messages will go somewhere else on the screen, so that's
not a big deal (a long thin thing is bad for messages).
So, level, score, health, all up top in a stack. Buttons to bring up help and
quit on the bottom in a stack. In between, inventory. Maybe inventory and skills
in an accordion view kind of thing?
Just got back from dinner and a date. Which is good since I was kind of out of
code when I left, now I'm ready to start again.
The good news is, I am not a failure yet: my initial goal for Saturday was just
the stuff I got earlier this afternoon: a guy, walking around, with a sidebar.
At this point I could start in on Sunday's stuff but I think I'd rather add in
an inventory system. I can probably knock that out tonight and then next week I
have a lot more freedom in what I can put in: potions, scrolls, keys, whatever.
I know that I pretty much need a game skeleton playable by this weekend because
I won't have time to do anything major to it next week. I can write enemies but
I'm not going to be able to implement something like a map generator in one
Last night went all right, not as good as I'd hoped. I had most of an inventory
system set up, but not everything. I had to finish it this morning. I think I'm
starting to butt up against the limits of LoveFrames, which is disappointing,
but it seems easy enough to hack so I think I'll be all right. Also I've got
almost all of what I actually want to do GUI-wise finished.
Right now there is armor, weapons, health potions, things in your inventory can
be worn / activated, used, wearable things have categories and only one thing
from a category can be active at a time (like, one armor / one weapon), and it's
even drawing the things you're wearing on a paper doll.
My schedule for today has a level generator and fancy walls. I know how to do
fancy walls so I'll tackle that first, but the level generator I haven't decided
yet: either something based on Wang tiles or something else.
Fancy walls are done. Easier than I expected by far: the wall art I have has
lost of different tiles, but since I don't need to draw a whole tile at a time I
can just grab four edge tiles and eight corner tiles (inner corners look
different than outer corners) and combine them. I'm not bothering with sprite
batches yet and I probably won't, since I'm clearing 60 fps pretty constantly.
Now level generation. I think I'll not put too much thought into this. The level
map is really only there to provide pacing and give the illusion of choice: if
the player just sat in one place and fought an endless stream of monsters, with
occasional treasure drops, the game would play pretty much the same. So it's
really just for looks, and I can fake something that looks pretty decent.
Maps! That look pretty good actually! I'm using the usual map algorithm, the one
I learned in college that I've probably coded a dozen times now. It works on a
square grid, connecting cells of the grid to adjacent cells through hallways, so
you get a maze-like structure. I made a couple modifications to allow hallways
to form loops (the usual algorithm makes a tree) and then I turn that into a map
by making each cell represent an 11x11 tile that I (might) place a random room
It takes a little time to make the maps because they end up being fairly large
once they're expanded, and doing stuff like placing walls becomes a pain. I'll
probably shrink the tiles to 7x7.
Also, an updated schedule for the first part of the week, since I know better
what will be doable:
Monday, I'm going to have a big day: minimap, visibility calculation, some
helper functions for dialogs and a "generating map" dialog since the map still
may take a few seconds to bring up.
Tuesday is all about enemies: I want an enemy class, basic combat.
Wednesday, I'm intentionally scheduling light, with just enemies dropping
treasure / gear, which should be easy. It segues nicely into what I originally
had planned for Thursday and Friday, and it also gives me a day to catch up if
I'm behind after Monday, which I suspect I will be.
My first weekday! Whee! Last night I got a minimap up, sort of; a little window
that will have a small version of the map in it. Tonight I'm going to do
visibility (which means I'll never have to type "visibility" in this blog again;
looking forward to that) and the populate that window with a minimap.
I'm going to do visibility a sort of cheap way: whenever you open a door,
the room or hallway on the other side of that door will all become visible. It
should work okay. I'd use libfov, and I even wrote a Lua wrapper for libfov, but
Love doesn't support native extensions so I can't. And I have no interest in
trying to implement raycasting from a blank piece of paper this evening.
And we have visibility. It took more effort than I expected: first I introduced
a bug doing something I thought was innocuous, which I had to find. Then I
discovered that visibility dropped the framerate from the 50s to the 20s; still
fast enough but worrisome, so I redid it. Now the rule is, when you open a door,
we find the connected un-revealed hallway or room, reveal it, then reveal any
cells adjacent to it (because those contain walls we want to see). Once there
are enemies I'll need to broadcast a room-entered event to them or something, in
case I want to trigger any enemy behavior off the player entering a room they're
Wow I made it. I have a minimap working, which is everything I wanted today
except a "generating map" dialog, and I'm pushing that to Friday because the map
generator is so much faster now that it's really not needed.
I'm going to hack out one last thing, a dialog for the "combat log" sort of
thing. I forgot about it earlier and since today is a lot of engine-related crap
it'll fit right in. The only other engine-y thing I'll need after today is
handling ranged weapons; prompting the user for a space and letting them click.
That can happen Thursday though, after there are enemies.
Enemies! They are placed on the map randomly, when you walk into them it attacks
them, and if you attack them enough they die. Right now they don't attack back,
but that's next. They need to move too, and follow the player when they're
awake, and for that matter wake up when you move too close (everything in the
dungeon is asleep until you poke it. It's dark, after all!).
Also it occurs to me that a lot of the other stuff in the game, like chests,
stairs, loot, all have a lot in common with enemies. I need a parent class for
things like that, like MapItem.
Last night I finished about what I expected to. I definitely overscheduled
Tuesday. Enemies are placed, you can attack them, and the hooks are there for
game flow (the enemies moving, waking up, etc) but none of them are being called
yet. I made a sparse array class that performs a lot better for storing map
layers that will be sparsely populated, like enemies, and then I got tired and
went to bed. Whose bright idea was it to have the 7DRL on the week of the DST
But I underscheduled today to compensate, so I should be all right still.
Enemies now chase you around, which was hard to do because I caused a fairly
thorny bug in the process, and they attack you and do damage. You can't actually
die yet, that's the next thing.
I was going to do some fancy A* pathfinding thing, but really, enemies will
probably never be far enough away from you to need it, so now they just swarm.
It works pretty well actually, they tend to get the maximum number of guys on
you at a time and take you down. I'll probably need to implement armor and such
soonish to make the game actually beatable.
Last night I stayed up long enough to get dying working (and "start a new game"
working when you die) and stairs, o you can go to the next level. I just got
through adding tooltips to the items to explain what they do, and making chests
work. Chests give you your choice of two items and then disappear.
Next thing (in fact, the last thing, and then I'm declaring success) is to have
a respectable number of items. 5 or so weapon types, at least three armor types
(maybe different armor slots, like 4 armors and 4 helmets), and a couple
miscellaneous items I had the idea for as I was playtesting.
I'm going to get the basic armor / weapons done tonight and then the misc stuff
tomorrow, then package it up to release!
And it's finished! Last night I had a playable game, tonight I made it a
(reasonably) balanced game, with some fun extra items. Download links are at the
top of the page.
Overall this was a hell of a lot of fun. I finished everything I wanted to
finish when the week began; the only things left on my wishlist are ideas I had
while I was writing it. I will probably go back and add some of that stuff, like
a magic system, and enemies dropping loot.
But first I'm going to catch up on sleep.