RIP cat mug. Many hours of development were fueled by your glorious ability to hold coffee. We did not deserve you.
金継ぎをやってみようきっかけかな?
RIP cat mug. Many hours of development were fueled by your glorious ability to hold coffee. We did not deserve you.
金継ぎをやってみようきっかけかな?
See more posts like this on Tumblr
#devtober #game development #indie game devTrying to squeeze in… probably a bit too much into the extended Devtober deadline. Holding a level-gen “mini jam” with a friend of mine tonight for just that reason. But sometimes, you just need to work on something completely different for a bit. Right now I’m playing with building out tooling/code for making a 2d open-world game in unity.
This is about where we’re at for the end of Day 2. Compared to Day 1, definitely racked up some more wins! I think up next the player will need a health and inventory system, then a weapon of some sort, and some keys which can bring them to the level exit.
Sometimes you have a rough night’s sleep, but when your coffee mug has cats on it, all’s still right with the world.
Well, Wednesdays are my dedicated language-learning day, so I probably won’t be doing much for Day 3, but hey - the project got an official spot on the cork board!
Over the last month or so, I’ve tried to get (back?) into creative writing as a hobby. Unlike the game design work I’ve been doing for many more months, I’ve managed to hang absolutely *none* of my self-worth onto creative writing; instead, with no illusion that I might be even remotely good at it, I can take as much energy I put in, and get exactly that much unmitigated enjoyment out. It doesn’t get filtered through self doubt, through my internal critic, or through my need for approval.
One of the books I’ve been using on this little nature-walk of a journey has been “Writing Fiction: A Guide to Narrative Craft”, by Jayne Burroway. Despite having picked my copy out from the library over two months ago, I’ve actually only gotten about… a chapter and a half through it. I’d say this was because I needed to spend some time warming up on writing exercises before going deeper… but I haven’t done a lot of that either. Yet somehow, just that much of it has totally re-calibrated how I think about creative expression. If you’ll excuse me quoting her quoting other writers, there are two bits in particular that have really stuck with me:
“What we call writer’s block,” claims novelist Tom Wolfe, “is almost always ordinary fear.” Indeed, whenever I ask a group of writers what they find most difficult, a significant number answer that they feel they aren’t good enough, that the empty page intimidates them, that they are in some way afraid. Many complain of their own laziness, but laziness, like money, doesn’t really exist except to represent something else - in this case fear, severe self-judgement, or what Natalie Goldberg calls “the cycle of guilty, avoidance, and pressure.”
The playwright Maria Irene Fornes says that there are two of you: one who wants to write and one who doesn’t. The one who wants to write had better keep tricking the one who doesn’t. Another way to think of this conflict is between your right brain and left brain - the playful, detail-loving creator, and the linear critic. The critic is an absolutely essential part of the writing process. The trick is to shut him or her up until there is something to criticize.
I think the last 10 or so days have, for me, has ended up following a similar theme: rediscovery of the playful nature of development; giving myself permission to enjoy the often messy and subpar nature of exploring a new design; and getting used to telling the perfectionist in me to shove off until he’s actually needed (which is not going to be any time soon).
With that said, I should quickly mention that I have released the first version of this project (dubbed shrl-proto.v1) here on itch.io! For all 0.645 of you who are interested, I encourage you to go there, download it, and give it a shot. For now, I’ve also create a short demo video of… well, pretty much the whole thing, so far.
My personal challenge for this mini-retrospective, staying on theme, is to turn off that bit of my brain that wants to do nothing more than exhaustively list every last way in which I’ve managed to fall short of absolute perfection, and to instead extract some positive takes from myself, no matter how much it pains me.
When I first started on this project, I mentioned that this survival-horror roguelike idea isn’t at all new for me. Instead, I had revived one of my first projects that I started when I decided to take the plunge into game development - a project that turned to an exercise in over-scoping, and rampant mishandling of milestones and deadlines. But when I look at what I’ve accomplished in first week this time around, I can really see how far I’ve come in the past few months. What probably took me about six weeks before, I’ve worked through in a fraction of the time! This is actual, tangible, progress, and I truly don’t know that I would have realized how much I’ve grown if I didn’t take a chance on this idea again (and the opportunity to reflect on it).
At the end of the day, what I’ve really wanted to do with this project is to evoke the stress of having to keep moving in a hostel environment with insufficient resources, and to my utter surprise, I can sense of bit of that starting to come together already.
There are a lot of ways to tackle the question of how things have improved, but I think looking at the weapon systems is solid way to make these ideas more concrete.
A lot of what has made this project go smoother than previous ones has pretty much just come down to doing a bunch of things I’ve done, by this point, a good handful of times before. When it comes to player movement, managing events through collisions and triggers, designing state machines for my actors… these are areas in which I’ve either had the time to make mistakes and iron problems out, or where I’ve simply built up a toolkit of techniques and just plain old code that I’m now able to reuse. But holy fucking shit, do I just not know the right way to handle weapons and inventory. Like, no fucking clue.
To illustrate how badly this can go, I dug up my original inventory code. The starting point here is pretty short, so I’ll just share that code in its entirety.
Now, part of what’s going on here is a technique I picked up from some resources out there about ways to use Scriptable Objects in unity (here’s one). And even now, I’ve still grown to like Scriptable Objects in place of static singletons for things like giving my camera prefab a reference to the player it should track, or giving my UI prefabs references to the right bits of player data to reference, or swapping around global references when I dynamically load new levels, etc. I like the flexibility I get from using Scriptable Objects in place of singletons, and this generally hasn’t made any other code more complicated than it would have been anyways. But, that alone is not what’s wrong here. To see what is, we need to look closer at this Inventory class…
Huh! It’s another Scriptable Object. I don’t want to get too into the weeds with Unity stuff right now, and there very well might be a valid reason to do something like this, but I want to try to breeze through exactly why this is so silly. Scriptable Objects are, in short, a way to create custom types of static assets which are saved as part of your game project, just like any 3d model, or a sprite, or a sound file. When they get loaded into the game, a single copy is shared around, and when you make changes to that asset in the game (at least in edit mode), those changes get saved permanently to the asset itself.
Maybe you can already see where this gets a bit silly. The player is going to end up getting a reference to this new inventory object to modify it with all the items they pick up and use, but normally that instance would end up getting serialized back to disk because, well, Scriptable Objects. But if that happens naively, the next time I boot up the same level, I already have all the items I collected from last time! So, we end up making a new instance, and we write code to ensure that that instance gets nulled out when the asset is no longer loaded.
The real answer to this situation, at least for me, has been: if you need data you can modify and share at runtime, put it in a damn Mono Behaviour (component)! That’s what they’re there for. This solution is over-engineering plain and simple. But notably, the only reason I did this in the first place is because I knew I had no idea what I needed from an inventory system, but I knew it needed to be perfect, dammit - so this is what we got.
What about now? Actually, if we look at how the player picks up other items compared to how they pick up weapons, we can see that there’s already some jank that’s made its way in.
So, normal pickups are scripts that take the player object and tweak it however they’d like, but the weapon is just a bunch of data and the player controller needs its own code to manage that? It makes some kind of sense, but it’s definitely not a Perfect And Clean Design. But you know what? At the end of the day it took me about 1 hour to design the medkit pickup, 2 hours to get the weapon pickup working right (plus some extra time to make sure that weapon firing was not a buggy mess), and about 20 minutes to create a new pickup for ammo. And you know what the difference was? All I did this time was ask myself the following:
When I started thinking about adding my little handgun weapon, my brain definitely went to a dangerous place. It went to a place where one asks “well, what would an ideal long-term inventory design look like, and how would that weapon fit into that?” And I was that close to designing another silly component that ended up taking two or three days to get right. But I didn’t! I said to myself “I need one weapon, maybe a few parameters that are easy to tweak related to timing, and the player is just going to plop the gun sprite into the game and spawn some bullet prefabs from it. THAT’S IT.” And so here’s what we got (from my player controller):
It’s fine. I don’t want to dump all the related code, but one can kind of figure out what the inventory and weapon classes look like. They don’t do much more than what’s needed here (and in the UI bits).
Alright, quick coffee break. (The cat mug returns!)
… And we’re back.
A few things pop out to me about what’s gone right this time around:
In short, this week has really been a journey in letting go of perfectionism, and accepting that shit code not only can get you to good code, but is necessary for getting to the game design quickly.
And well, there we are. I originally wanted to include some thoughts about plans for my next milestone, but I didn’t realize I’d have this much to say! So that will end up being my first-thing-in-the-morning-task, and I think we’ll all be better off for it : )
Until then!
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 ought 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!
And so we begin this devlog, one fine fall morning; a bit more tired than I should be at this hour; yearning for another coffee but forcing myself to get started anyways. The devtober challenge technically started three days ago, and I snuck a bit of work into my project over the weekend, but to me, today feels like my true Day One.
As a neophyte developer, my biggest struggles have been:
And so these will be the skills I’ll try to focus on, and hopefully demonstrating in these devlogs!
This brings me to my choice of project, which has its own set of pain points:
My personal projects tend to fail on one of these two points.
With that in mind, the first game I thought of to focus on was a platformer I’d been toying around with. It features, so far, an intrepid, anchor-wielding explorer (possibly influenced by a recent fighting game I’ve been playing) who has to wander across a desert landscape to find… something. I hadn’t quite figured out what yet, but the energy of the idea resonated with me enough to get the ball rolling.
A platformer is practically the ideal sandbox for the aspiring developer: the core components are mechanically simple (a state machine that controls different types of movements, with some knobs to tweak until you’ve got that feeling just right), then it’s just a matter of building some interesting objects to interact with, and mixing and matching them to see what ends up being fun. For learning game design, and not just game programming, it seems pretty much ideal!
But for some reason I’ve felt compelled to return to a project that failed spectacularly on point 1 - Death by Over-Scoping. But more than that, it was also a spectacular failure to focus my efforts on what really mattered when prototyping a design. A lot of my effort went into things like animating a bunch of sprites I knew I probably wouldn’t keep anyways, or spending hours on free sound websites to get just the right THUNKS to use when my enemies whack a door, … and so on.
Now, there’s probably something to be said for trying to evoke a target energy early, but did any of this help this neophyte developer learn the ways of the game designer? No! Of course not. It totally derailed the project. So why return?
On some level, I have absolutely no idea. But there’s always been something that’s drawn me to this concept on an emotional, evocative level. Taking my favorite parts of the survival horror genre… always being on alert for what might be around the next corner, always feeling like you’re about to run out of your resources, always knowing that the enemy is just stunned and it will be coming back for you… I still felt that taking these feelings, and trying to distill them into a randomized, repeatable experience would be worth trying again.
Anyways, I have the whole month ahead of me, so I should leave some amount of ranting for the weeks ahead. There’s quite a bit of work remaining, but hey! I have a circle carrying a flashlight, and that’s a start!
This is what you get when you let programmers make prototype art: negative time to penis. “What could go wrong?” the programmer thinks, “I’ll just make the attack a triangle for now.”
This one’s a pretty straightforward drop! As always, the zipped release is available on my itch page for windows. (Still having UI issues with Mac, sorry!)
Unfortunately, I’ve only been able to get what is on average 2~3 hours a work done for a handful of days every week, which hampers the momentum of it all a bit, but I have some other things in the works right now life-wise.
So the new enemy type still needs more work before I properly put it into anything I release to the world, but there’s a new weapon I’ve played in the (currently only) level. Between that, some important fixes to the enemy behavior, and some item and enemy placement, I think there’s enough here to merit a release.
The firegun and enemy, even though they didn’t take a ridiculous amount of effort, did a lot to complete the feel of the game. I’m still not sure if having a weapon which just out right one shots enemies is the right design choice in the long run, but at the moment it comes with very little ammo and the player has no way to obtain more. Plus, as the player nears the end they tend to get swamped by boatloads of enemies, so in the current iteration it helps things click.
The placement of items across different quadrants did a lot to also help smooth out the play experience. Levels still feel like they’re more or less different every time, but it feels less like whether or not you make it to the end depends on the luck of the draw with item placement. I still have qualms about the experience being too predictable, but I know what the underlying logic is, so playtesting it with a few friends who didn’t design the levels would probably help me understand how confusing the map is, or up to dumb luck their victories felt.
At the end of the day, one would want the “true version” of the game to rely more on leveraging your wits and figuring out the exploration puzzle of it all on the fly rather than over-using a priori knowledge of the level design, but the amount of predictability the level has right now would actually feel right for an introductory experience.
And as always, I’m weirdly proud of my sound effects, and weirdly ashamed of how bad programmer at looks : )
Last week I shelved the game dev projects so I could focus on job applications and some health and wellness nonsense. In retrospect, I might have overdone it on the job app all-in - it seems a lot of my general joie de vivre comes from my creative projects!
Not that the week was a total wash for me creatively - far from it. I’ve stutter-started trying to pick up drawing as a skill, and I think I sat down to do more drawing over about five days than I’ve done in my life to date.
On top of that, I sat down to right a short section of fiction for… basically the first time in my life, excluding some truly abortive attempts in high school. I ended up with about 1800 words that were shockingly un-awful! I had a friend whose taste I mostly trust look it over, and was told it was “cute”, “evocative”, and that “I’ve read much, much worse”. I might even try to finish it up as a short story?
The interviewing and all that is really going to ramp up next week, so here’s hoping I can keep up on these smaller creative projects and stay a little sane!
Just for fun, here’s some of the music that’s been keeping me sane this week: