I feel like I need to preface this with so many things that unless I list them all here to get them out of the way, I won’t ever actually start this goddamn blog post. So here:
- I have, in the back of my head, an idea for a method of representing and studying metroidvania games.
- This system (for which I have no name) is nowhere near complete. In fact, I keep thinking about and adding to it every few months.
- This system (such that it is) exists more or less in my head. I had implemented it in Python, but I got too bogged down in fixing the nitty gritty of the code rather than focus on the design of the system.
- Since I want to actually design the system, and I wasn’t getting anywhere with a pen and paper, maybe switching to a different language/paradigm would offer a nice new canvas from which to draw inspiration.
- That brings me to Haskell. Or rather, functional programming in general. My first brush with functional programming was when I coded a little game involving knots way back when for a college project (I believe there are posts about that here on this blog). Unbeknownst to me, I had coded the whole thing in a functional style. It was a very mathematical problem and hence most of the code was a composition of pure functions. I think I think functionally when it comes to code by default.
- Another thing that brought me to Haskell was a lecture series on Category Theory by Bartosz Milewski, where he used a ton of Haskell examples.
- Oh okay I can stop my list now.
So now what do I write here? Do I explain my system? I don’t think we’re quite there yet. But okay whatever. Here’s a skeleton outline of what I managed to implement in Haskell:
- There are Abilities.
- There are Challenges you can pass only if you have the correct set of Abilities.
- There are Rewards for passing Challenges.
- There are Encounters, which are tuples of (Challenge, Reward).
- There are Rooms, which contain paths to other Rooms, and maybe Encounters.
Those are the basics. The suuuuper basics. To expand:
- Abilities form a partially ordered set, in that some Abilities supersede (are greater than) others when it comes to certain Challenges. A concrete example would be a sword that does 10 damage supersedes a sword that does 5, but it doesn’t compare to a double jump ability. You the player start with Ability 0.
- The most basic Challenge is analogous to a locked door. If you have the correct set of keys to open all the locks, you can open the door/pass the challenge. That’s the version I’m going to implement here. Obvious modifications from analogy are to implement a sort of additional “skill” check, in that merely having a sword is useless if you don’t know how to use it well.
- A Reward can be a new Ability, another Encounter, a path to a new Room (or a shortcut back to an old one), or Victory.
- Encounters are not just a bundle of (Challenge, Reward). This is where you implement your story/lore/plot/atmosphere/mood.
- Rooms are tricky.
Rooms are the bits I have the most trouble with. Another blog post about that someday.
I know this stuff seems very bare bones, but it needs to be if my goal is to recreate an existing metroidvania in this system in order to analyse it. I’m already a fair bit into mapping out Environmental Station Alpha, analysing the first few areas, and I’ve already found some cool patterns. My hope is to compare it to Axiom Verge and see if I can explain my relative dislike of that game compared to ESA. Don’t get me wrong, they’re both great, but I think AV lacks something that could have made it truly excellent. And I’m hoping to find out what, if anything, that is!
I think that’s enough for today. I’ve titled this post “Messing around with Haskell”, perhaps prematurely. I’ll rename it to something more appropriate and get to the Haskell bits some other time. “Breaking down a metroidvania (Part 1)” because I’ve mentioned at least two other posts here. This title is worse because I haven’t even explained what a metroidvania is. Oh well, another post.