Looking Back, and Looking Forward


(You can see this on my personal blog here. There's a working video on that site, where this devlog had to get by with a gif.)

So as it turns out, I am still working on game projects. One of the recent things that's been an excellent break from the usual routine has been a Go-inspired game, which I've been prototyping in gaming's latest technology: a google sheet that I keep copying around and linking to people who want to play. It's been a fun chance to develop something in a way that's focused entirely on playtesting with other people, and honestly it's also been a great way to reconnect with folks I haven't seen in a while and have a good laugh about how utterly terrible some of my design decisions have turned out.

But when I look back to my survival-horror rouge-like (SHRL) project that I'd started during the (quite fun and well-run!) Devtober game jam, I was struck by how much change can occur to a person in such a short amount of time. I don't want to dwell on precisely what's changed (though, some might be able to read between the lines), but when you take a project that constituted about a week's worth of work done over three, then fix the level generation and absolutely blow through your bug list in the span of about three days, you know you've made the right changes. The lessons I learned about setting aside perfectionism will continue to be invaluable, but they don't amount to much until the machine in your head that turns enthusiasm into action gets the TLC it needed.

It's still a bit difficult to reflect on my work done before we Did The Thing, but we can try to! I remain equal parts proud and openly critical of where I've landed, but I've learned to love a project this prototype-y for what it is, and what it ough to be at this stage. The basic feeling of having to hurry around a hostile environment, get past monsters that you can't really kill, and squeak through to the end is there, if rough around the edges. And the little bits of sound design that really pop to me (the gunshots, the swipes of picking up a card, the dragging creaks of the doors) are something I had no hopes of being good at, and so I can admire them all the more openly.

The random level generation was definitely a Big New Thing though. From the get-go, I knew I'd have to hold back my impulse to build a room by room graph, then try to figure out how to tile everything, place enemies and items in the right spots, make sure the levels end up interesting from there... etc. Basically, this wasn't the right time to Computer Science the problem away. So I took some inspiration from talks I'd seen on games like Spelunky, and tried to pre-build interesting bits and pieces and stitch them together in an interesting way. The most basic version of that I could think of was to create four game sectors, each with their own potential player spawn point, item points, enemy spawn points, and so on. These sectors could then be flipped and rotated around, and placed into the four different corners of the overall level space. That was the idea from the start, and it stayed pretty much consistent as I worked on it. You can see what building the sectors looked like here:


And what it looks like (with test lighting turned on) here:


The way that the tech came together was... well, it's a slight mixed bag. My goal from the get-go was to make laying out sectors and the design part of the process as easy and convenient to do in the editor, and to have scripts deal with generating data structures that made the final layout and assembly as easy as possible from a coding perspective. And we more or less got there, but there were some rough edges that fell out of smaller decisions I made as I went along.

Let's look at how sector layout ends up working:

There's some good stuff here. Laying out rooms comes down to just modifying Polygon2D colliders, so I was able to leverage something unity is already good at. Laying out spawns also came down to just putting some prefabs in. Then, when you click on the "Generate Rooms" button in the Sector component (on the top-level sector object), all the points on the polygons and all the spawn points get snapped into the grid position they're closest to. Very handy indeed!

What I'm less sure about is how this ends up getting translated. One of the things I was concerned about, was what the best way to combine different sectors would be: ensuring that all their tiles and spawns end up in the right place, and making sure that when I "drew the seams" between two sectors, I was properly able to identify the selected joints in both, erase the walls there, and draw a single door to replace them.

What I ended up doing was pulling all the information into pure C# data structures on the Sector component with the "Generate Rooms" script. This made laying things out in the final level much easier, I think, than if I had to crawl a bunch of components, delete the stubby objects, and add the proper ones back in, but I still wonder about if I had gone the route of making the pre-designed sectors more identical to what they would end up being in game. Having separate tilemaps and just using the transform to rotate/flip "felt wrong", but maybe I should have given it more of a try. That said, I'm still proud of using a custom editor to add a button which would set everything up for me after just moving around some prefabs and polygons. Editing ended up being more finicky than setting things up initially, but not horribly so. I probably could have also put that data into a ScriptableObject of some sort, so I didn't have to pass the whole sector object to the level generator, but that's a simple optimization to make down the road.

There ended up being about 1,000~2,000 lines of code involved in level generation, but a vast majority of that is pretty uninteresting. So instead of diving in further, let's take a break for now. Here's a mug I picked up in Chicago, with their wonderful flag on it!


When I back away from how this project has gone, and instead look forward towards what I want to do with this it, I see two sides to that coin. The first is pretty straightforward; it's simply what I want to try next in the game. I noticed that the enemy AI became a little less aggressive at some point, and they could probably use a little attention in terms of their ability to really hound and pursue the player. Doing something clever - like have a group AI that assigns enemies different positions around the player - could be interesting, but for now something more like adding a less hacky form of pathfinding in could go a long way. Another enemy type could be fun too - I've been thinking about a static defense sort of creature that calls other enemies (either with sound, or maybe spores?), really raising the tension that can happen when the player screws up. And the player could probably use another tool in their toolkit - a low-ammo weapon that can actually kill enemies is an obvious place to start, but I've also thought about something of a sound/spore grenade that would distract them (and would pair with the alarm enemy in a thematically interesting way).

The other side of that coin would be how can I use this project to further my own learning and growth. And honestly, that's the side that's probably disproportionately interesting to me, and boring as all heck to an outside observer. But I really do want to see if I can analyze my design and gameplay decisions in a more critical way, and to push my abilities to iterate on what I've learned and incorporate them into the game, getting it from "I can see how this might be fun" to "I'm actually starting to feel the fun".

I don't know if this project will end up even being something I'd even publish as a proper browser game, much less a proper release - the Go-inspired project might be more in that vein - but I'm excited to see where it can go. And as you can see below, I still have plenty to do!


Files

SHRL (proto.v2).zip 25 MB
Jan 26, 2022

Get SHRL (Untitled)