Posted April 29, 2024 by serfofcinder
From the earliest stages of development, I always wanted this game to have a grappling hook. I made one pretty early on, and it is the one feature I have reworked the most in this game.
The header is pretty clear. When I first started developing this game, the goal was just a straight “Doom, but a Metroidvania.” And I still find it funny to mention that I started developing this during a game jam where the theme was “Cozy”. Very appropriate, both in terms of theme and scope. /s
So the original version of the game had a weapon wheel. You selected your gun from the wheel, and then you shot it. The weapons were: the pistol, not very strong, but the only gun with infinite ammo; the shotgun, very powerful but short range and not very fast; the laser, fast damage over time, but with no knockback; drill, which was supposed to be like the chainsaw from the recent Doom games (it never got there); the mine launcher, which could not only launch devastating explosives for the enemies, but the mines would also stick to walls and you could use them as platforms; and last, but not least, the grappling hook, which was not an offensive weapon, but a mobility device. Here’s how it worked.
For all my talk in the previous dev log about wanting to intuitively know what a parameter means and not have to just mess with the value until it feels good, that is what I did with the grappling hook force. I couldn’t think of an intuitive parameter to be able to set other than just the force magnitude.
But I played around with the value and arrived at something that felt satisfying. There were several interesting quirks of this system:
Jank aside, this was a satisfying system to pull off some stunts in.
Then came the big narrative change where I decided to also bring in Avatar inspiration. That meant all the guns needed to become elemental powers instead. So now the grappling hook was a water power, because of surface tension or something. And mechanically, that changed… nothing. I made a new shader for the line, to make it look like water, and that was it.
Like I said, this system had some satisfying stunt potential. The trouble came when I had to actually start making levels for it. The problems that I found then were numerous.
So, I played a lot of games featuring grappling hooks for research.
I had already played Ori and the Will of the Wisps, and loved it. One of the many (possibly too many) abilities in that game is a grapple. There are two possible grapple targets: blue hanging grapple points that you could pull yourself to and through, and blue grassy surfaces on floors, walls, and ceilings that you could pull yourself to and cling to. And the aiming happened automatically. I originally didn’t want a system like this because I wanted it to be more freeform, and less bespoke where you could and couldn’t grapple. But Ori’s system did solve a major problem I was having: Ori had the flow. You don’t have to stop and precisely aim your grapple. You just do it. Grapple from a jump. Grapple from a running start. The game will know where you meant to aim. It just works.
Flinthook is a stupidly difficult roguelike game prominently featuring a grappling hook. The grappling hook in this game latches onto bespoke points, and pulls you straight to and through them, similar to Ori and the Will of the Wisps. Ori has much floatier physics, which I think feels good after a grapple. Ori is more interested in giving you a sense of momentum, while Flinthook is more interested in keeping you highly active and precise in your movements. I’m leaning toward precision over momentum myself. But I am starting to notice a pattern. Bespoke grapple points do take away the trouble of precisely aiming, and allow you to move around more fluidly.
Rusted Moss is an interesting one. The grappling hook in this indie metroidlike is freeform, and you have to precisely aim at a particular type of surface to grapple onto the precise point you hit. Then the grappling hook is stretchy and fully physics-driven. You can do some cool tricks with it once you master it, but it is a steep learning curve. Rusted Moss can get away with that because the grappling hook is the marquee ability in that game. My grappling hook is just one of a dozen abilities. Rusted Moss also gives you a bit more precision by requiring mouse and keyboard controls. That makes your mouse aiming more precise, but all of your other platforming with the keyboard less precise. My game requires a controller, which makes precise running and jumping easier, but makes precise aiming harder.
This is not the grappling hook I’m looking for.
I found the grappling hook of my dreams in this ball-crushingly difficult speedrunning platformer. There are two archetypes of grappling hooks: those that pull you in, and those that let you swing below. Ori and Flinthook have the former, while Grapple Force and Rusted Moss have the latter. Mine was some kind of hybrid of the two, owing to my leaving gravity on while you grappled. But Remnants of Naezith allows you to do one or the other. When you press the grapple button, you shoot out your grapple at a 45 degree angle up and forward. If it hits a grapplable surface, it latches on and you start swinging under it. If, while swinging, you press the jump button, it pulls you straight in. It’s extremely satisfying, and pretty easy to get the hang of. It’s expressive, allowing you to swing or pull in to fit the situation. The timing of releasing a swing or pulling makes a big difference for your movement trajectory, so there is a sense of mastery in getting those timings right. It automatically aims, so you only have to worry about the timing and the movement of your character. The difficulty just comes from the level design demanding pixel perfect and frame perfect precision. Rusted Moss could have never gotten away with demanding anywhere as much precision. This is the one. This was how I wanted my grappling hook to work.
But I did make one change. I opted for bespoke grappling points instead of automatically aiming up at a 45 degree angle. That gives the player the ability to just aim in the right general direction, and the game will fine tune their aim toward the correct grapple point. And it allows me as the level designer to know where the player will be latching onto, and be able to put grapple points directly above where the player will be so they can pull themselves straight up.
Now, when you press the grapple button, it will find the best grapple point candidate based on:
And your grapple goes straight to that grapple point.
As I wrote in my previous dev log, my character controller is a big state machine. So I added two new states: GrappleSwinging and GrapplePulling. And now I get to talk about physics again. I’ll describe each one one at a time.
There’s a physics concept called Simple Harmonic Motion. That’s why, when I text, I type shm to mean shaking my head. My head is undergoing simple harmonic motion.
I’ll be here all week.
This is a form of motion where a restorative force acts on the object proportionally to its displacement, causing a steady back and forth movement. The two common real world examples are a spring and a pendulum. The further a spring stretches, the more force it exerts to return to its equilibrium length. So, if you have an object hanging from a spring, pull it down, and release it, it will spring back up, past the equilibrium length, and then have the spring exert a force on it the other direction. And it will move back and forth like that forever without any damping force.
The further a pendulum swings, the more directly gravity pulls it back toward the center. So if you pull it to one side and let go, it will swing back down past the center, at which point gravity will start pulling it the other way, back toward the center, and it will keep swinging back and forth like that forever without any damping force.
Of course, in the real world, there are damping forces. A damping force is a force that acts on an object proportionally and in an opposite direction to the object’s velocity, causing its speed to exponentially decay. The most common real world example of a damping force is wind resistance.
Without damping, if you graphed the displacement of an object hanging from a spring over time, it would look like this:
You may recognize this pattern as a sine wave. The exact function I used here was:
However, with damping, the graph will end up looking more like this:
The oscillation amplitude decays over time. Mathematically, this is the result of the sine function being multiplied by an exponential decay function. The exact function I used here was:
Now why is all of this relevant to my grappling hook? It may be intuitive to think of the grappling hook swing as a pendulum. And it is. But the more important math here is actually modeling it as a spring. Springs have what’s called a spring coefficient, which is generally represented in equations as k. More rigid springs have a higher spring coefficient, and more flimsy springs have a lower spring coefficient. The formula for the force a spring exerts is:
That is, the force is equal to the spring coefficient times the distance it is stretched or compressed from its equilibrium length. And that formula is how I calculate the force for the grappling hook to apply to the player character. I set my spring coefficient to 400. Meaning, for every 1 meter the grappling hook is stretched, it applies 400 N of force to the character. Quite a bit of force, and that’s good, because it’s not meant to stretch much. And here’s what it looks like in game:
Obviously, I’m going to need to add some damping. A damping force, as mentioned previously, is a force that acts proportionally to an object’s velocity, and in the opposite direction, causing all speed to decay exponentially. So, the formula for damping force is:
Where b is the damping coefficient. Now, there are broadly three classifications of damping with harmonic motion:
Underdamping, which will reduce the amplitude of oscillation over time, but not stop oscillation on the first cycle.
Overdamping, which is so severe that it will significantly slow the return to equilibrium and not allow any overshoot, meaning no oscillation.
And Critical damping, the Goldie Locks of damping. It is the bare minimum amount of damping required to prevent overshoot, meaning no oscillation, without slowing the return to equilibrium more than necessary.
The damping coefficient necessary for critical damping with a spring can be calculated as:
If b is less than that value, the system will be underdamped, and if b is greater than that value, the system will be overdamped. I won’t go into detail on the math of how that formula is derived, because it is pretty complex and not the point of this dev log. If you’re interested, here is the resource I used to learn about this: https://phys.libretexts.org/Workbench/PH_245_Textbook_V2/14%3A_Oscillations/14.06%3A_Damped_Oscillations.
Anyway, I want critical damping in my grappling hook, so I can calculate the value of b necessary for that. My k is 400, and I’ve left my character’s mass as 1, since the grappling hook is the only thing that directly applies force to it, rather than programmatically setting velocity. So the damping coefficient I need is:
Now, when I go to apply this damping force, I need to do one more thing. I don’t want to damp the character’s swinging motion; only their motion toward and away from the grapple point. I want the swinging to continue at full speed and build a satisfying sense of momentum. So, I break the character’s velocity vector into two components: one in the direction from the character to the grapple point, and one perpendicular to that direction. And I only add the damping force based on the first component.
And here’s how the end result looks:
There’s less physics to the pull state than to the swinging state. I created a parameter for grapple pull jump height. Basically, that parameter means “how high would I want the character to go after completing the grapple pull, if they grappled straight up, and they were under the jump button held gravity?” That sentence requires some context from my previous dev log on the character controller in order to make sense. I calculated the grapple pull speed necessary to achieve that height, similarly to how I calculated necessary jump speeds to achieve target heights in the previous dev log. I set an acceleration time, and calculated in code the acceleration rate necessary to reach that speed in the appropriate time. Then, I calculate the force necessary to achieve that acceleration, which is simply:
Good old Newton’s second law. So, on fixed update, I add that force in the direction toward the grapple point. I added a little bit of extra code to ensure that the character doesn’t exceed the max speed. That would basically recreate the bad grapple of the original iteration. So, to fix that problem, upon entering the grapple pull state, I set the character’s gravity scale to 0.
Then, there is damping once again. For pulling, unlike swinging, I want to damp the component of your velocity perpendicular to the grapple point, instead of the component parallel. In other words, when you’re swinging, I want you moving perpendicular to the grapple point. When you’re pulling, I want you moving toward the grapple point. In both states, I want to damp the other component of your velocity.
Once you are within a threshold distance of the grapple point, or you release the grapple button, the character transitions to the jump button held state. I set the threshold to be just greater than the exit velocity “jump height”, so the exit velocity doesn’t make you bonk your head on the ceiling.
While playtesting, I noticed one other problem with the original grappling hook: the weapon wheel. You had to select the grappling hook in the weapon wheel to grapple, and then you’d need the regular gun again to shoot a switch to open a door. So you’d need to go back into the weapon wheel to switch back, and then open the weapon wheel again to switch back to the grappling hook for more platforming. It was tedious.
So I did away with the weapon wheel, and assigned everything to its own button. Now the basic “pistol” gun is on RT, and the grapple is on RB. Problem solved!
Then I saw another game featuring a grappling hook, and just had to make some changes to my grappling hook to be more like it. That game was Sanabi. Sanabi is a neat cyberpunk thriller platformer with a grappling hook that works similarly to Remnants of Naezith, and thus, this game. The big difference between Sanabi and Remnants of Naezith, in terms of gameplay, is that Sanabi is much more forgiving, and interested in giving you a fun fantasy rather than requiring mastery.
So there were a few things I saw here that I liked:
So I made several corresponding changes to my game:
In conclusion, steal from the best. That’s kind of the premise of this game. Most of the other abilities, I copied straight from other games, and they just worked, because they were already great in those other games. The dash, wall jump, down slam, and the shotgun pogo are straight from Hollow Knight. The blaze of glory kickoff and the glide are straight from Ori. The parry is from the couple most recent Metroid games. The double jump is straight from every Metroidlike. The glory kill is straight from Doom. The grappling hook started out as its own thing, and it was bad. I reworked it to be like my favorite grappling hooks from other games, and it got a lot better.
Now I’m not saying that you should just copy everything. But if something in your game works differently than every other game, there might be a reason no other games have done it that way. We are also at a point where, when players see a particular ability, they have expectations of how it will work based on the other games they have played. So it is wise to play games with similar mechanics to yours, and familiarize yourself with how it works in those games, so you can both learn those expectations, and learn what makes that mechanic good in those other games, so you can translate that into your game. Once you understand that, you can make it your own. My grappling hook works similarly to Remnants of Naezith and Sanabi now, but it is my own version of that, not quite the same as either of theirs.
And, you know, math is cool.
Here’s what the finished ability looks like in action.