Wednesday, June 10, 2020

Something like a Summer Devlog, Part 4: Flying Leap

The TL;DR

I made a thing! Download it from the itch.io or check out this short gameplay video:

The Whole Story

As predicted in my previous post, I decided to participate in the 2020 Unreal Spring Jam. I have never participated in this jam before, but it seemed to come at the right time for me to explore something new. My May prototype had essentially been abandoned, and I wanted to make something interesting and publishable before having to switch gears to preparing for an as of yet uncertain Fall semester.

The jam was supposed to have started with a livestream, but for undisclosed reasons, Epic simply posted the theme to their variuos channels. I expected the same kind of theme I've seen in Global Game Jam or Ludum Dare, so I was caught off-guard by this one: "What is hidden in snow comes forth in the thaw."

About the Theme

It was amusing to watch the confusion on Twitch that went along with this theme announcement. I think many people were not expecting something like this. It could be interesting to see how much of the confusion was from people whose English is weak versus those whose poetry is weak. There were plenty of comments like, "So we have to have snow in the game?"

What struck me as most interesting about the theme, though, was how it seemed, inexplicably, to have a dark tone. Despite my efforts at whimsy, my mind kept turning to themes of people with secrets they never wanted revealed, but which would inevitably be revealed. The theme also pushed me toward storytelling, toward a narrative style of design, to capture these dark themes. This struck me as interesting because I know what actually is hidden in the snow that comes forth in the thaw: life! There's nothing dark nor morbid about spring blossoms and vernal pools.

Perhaps a key to this interpretation is the use of the passive voice: "what is hidden..." It implies an unknown actor with agency rather than natural systems. It would be an interesting experiment in creativity to take another group and give them the variation, "What emerges in spring," then see what kinds of games they make.

I spent a few hours thinking about the theme, comparing it to my mental lists of genres I want to explore and technology I want to try. It got rather frustrating, which is likely why I escaped too frequently to look at the funny comments on the jam Twitch page and Unreal Slackers channel.

One of the difficulties I had in conceiving of a good idea for the jam is that, as usual, I wanted to make a game in which the mechanisms reinforce the theme. I'm not as interested in making narrative games as I am in system-based ones, but the narrative edge of that theme kept cutting at my imagination. Eventually, I decided to punt and make a game about an idea that had been kicking around in my head for a few weeks anyway, and I could wrap it loosely in the theme as I went.

Flying Leap

I had a vision a few weeks ago of a game in which you control the arms and legs of a humanoid character as you hurtle through space toward your opponent—think wire-fu meets ragdoll physics. I had heard talk of Unreal Engine's Control Rig system, and I finally found an excellent explanation of how to use it on a little-known podcast. Finding this link was one of many times I have been grateful for the helpful folks on Unreal Slackers. I had actually built a very minimal tech demo of Control Rig in the days leading up to the jam, so it was fresh in my mind. I decided to go for it.

Unfortunately, not long into the development, I ran into a bug. I had actually seen it in my little tech demo leading up to the jam, but I had dismissed it as my own misunderstanding. After getting into it with a project in mind, there was no avoiding it: something seemed to be wrong with Control Rig's "propagate to children" option. To make a long story short, I lost a few hours to this before deciding to just abandon Control Rig as an approach, but that didn't stop me from pulling together a bug report. As of this morning, the bug has been recognized by Epic's QA team. There's a certain relief that comes from having someone at Epic tell you that, indeed, something is wrong, and it's not just you doing something wrong.

If I could not use Control Rig to manipulate a character's limbs, what's another option? I came across this four-year-old live training video from Epic that gave me a path forward: physical animation. A quick tech demo showed me that I could use the physical animation component to control the limbs of a character while blending that with forward kinematic animation, and then when necessary, flip over to ragdoll physics.

Another of my goals for the jam was to use some of the low-poly assets from Synty that I had bought as part of a Humble Bundle deal. Browsing my library, the Samurai pack caught my eye, and I could see a far-eastern theme matching the crazy control scheme. I brought in a few characters from the pack and retargeted the Mannequin animations to them.

I built a test level using other assets from the pack, enough of a level that I could get the gameplay working. Later into the project, I rebuilt the level more intentionally. I had never really done any significant level design before. The levels in Kaiju Kaboom were my first time using the landscape tool, but there wasn't much to them. For Flying Leap, I created the level out of meshes, placing scenic items here and there. It was also my first time using the foliage tool to place some flowers and bushes. I wonder what a level design professional would think of it. I'm sure it's not great, but I think it suits the purpose. The one part I am particularly proud of is the arch set back in the mountainous area, which implies a path through the mountains that doesn't actually exist.

Here's an interesting technical detail that I discovered which really surprised me. In the game, you control your left arm with the left stick and your right arm with the right stick, and you control your legs with the shoulder and trigger buttons. At first, I used axis mappings for both sticks in order to read the values and apply them to the physical animation. It was not behaving as expected, and I discovered that on the left stick, pushing forward was positive Y and pull back was negative Y, but on the right stick, pushing forward is negative Y and pulling back is positive. While it may be true that this matches a conventional use of game controllers, where the right stick is controlling a camera, it is really counterintuitive for development. Why should the two sticks map to different values? Fortunately, there's an easy way out: if you listen for events instead of axes, the problem goes away.

Fun

Is it fun? Well, my four boys think so, and there's a real sense in which that's all that really matters. I did have something of a crisis of faith around Sunday night. I had hoped to have core gameplay done over the weekend so that I could spend two days just on polish and juice, but technical problems and misjudgements meant I was still struggling with the core gameplay. For example, one thing I should have seen coming is that there's no technical difference between my punching your torso and your torso “punching” my fist. In any case, around Sunday I was developing misgivings that the game was not fun. It certainly worked as a toy, but I had a hard time finding the game. In the spirit of jamming, I decided to charge forward and just make it as fun as I could.

The core mechanism I ended up with is that you have to strike with your hands or feet in order to get any points, and that first strike will give an impulse to the opponent that scales quadratically with the speed of the strike. This has some fun effects when you pull it off, but recognize that because of the unconventional controls, it is kind of hard to pull off. Also, there's a related problem: in order to get any kind of reasonable collision in mid-air, both characters have to go ragdoll at the time of the first strike. Otherwise, the ragdolled one will fly right through the kinematic one. The result is that if I hit you with great force, you spin out of control, hit me with a very-fast-moving limb, and then I spin out of control as well. I ended up having to clamp the possible impulse values in order to mitigate this. It seemed like the right thing to do for the game, even though without it, the results were pretty funny.

Points aren't earned directly for the strike, although perhaps that would have made sense. I liked the idea of trying to push the opponent back as far as possible, so I made points earned for the distance you travel from your starting location. Originally this was measured in centimeters, but right before the end of the jam, I pulled it back to meters. In retrospect, decimeters probably would have been a good value, since now it's hard to differentiate and you get more ties than intended.

There were many ideas that I did not have time to pursue in the game. For the sake of sharing, here are a few that I think would make for good experiments and potentially add enjoyment.

  • Give bonus points for varying how you hit the opponent (right foot, right hand, left foot, left hand).
  • Allow for varying speeds of approaching the leap, to permit aggressive vs conservative strategies.
  • Allow slight left or right deviations from a straight line path, so you can try to line up an intentional strike with the other side's limb.
  • Headbutts, butt-strikes, and related acrobatic bonuses.

This is a good place to share one of the most interesting things I discovered during the design and development process. As the characters approach each other, there is a time dilation effect that I quite like. It probably should be more obvious in the finished game, since I had toned it down a bit during testing. In any case, during development I decided to add a soundtrack, and I was glad to find some wonderful public domain arrangements of traditional Japenese music. I chose one to play as a theme during character selection, and I set up another three or so to randomly play during the battle. However, during testing, I realized that this was actually working against the time dilation design: because the music proceeded at a continuous rate, it made the intentional dilation look like a buggy slowing down of the physics simulation. I ended up pulling out the music and instead just playing a subtle wind sound during the battle, and the music comes back after the round is over. Indeed, I think this alternate audio design is actually better, but I wouldn't have gotten there if not for the observation about how the music and the gameplay were working against each other.

Another feature that I would have liked to add is a way to access what I called “Limb Test Mode.” I have a level set up that loads up a character and lets you just experiment with the control scheme. It's actually kind of a fun toy in itself. I just ran out of time to incorporate it in a useful and accessible way into the game.

Let me wrap up my thoughts on fun my sharing what I think is the best part of the game: the narrative. Another thing I'd never really done before is add any kind of authored story to the game, but in Flying Leap, there is one that plays on the main screen. I had experimented with some different approaches of trying to convey the minimal story of the game, and I ended up with a simple text overlay. If you have the game, even if you cannot play it with some friends, I'd love to know what you think.

Other Thoughts

Five days is too long for a jam. Five days is a job, not a jam. I put an unhealthy number of hours into Flying Leap. Sure, I took some time to walk or bike with my family and throw the frisbee around, but I figure I worked about thirteen hours a day on average. It was fun, and I learned a lot, but I'm still not sure it was good. A 48-hour jam like Ludum Dare or Global Game Jam is a good timeframe to put your head down and sprint. For five days, though, this project absolutely dominated my attention. It's a bit much. That said, I don't know if I would do it differently if I could go back. When I think about the things that I would change, they are mostly about not wasting hours going down blind alleys and dead ends.

To sum up, through this project, I was able to explore several ideas and technology that I had never used before. While Control Rig didn't work out, this was the first project of mine that included: physical animation; incorporating ragdoll physics into actual gameplay; level design; retargeted animations; 3D gameplay with local multiplayer; incorporating explicit authored narrative; sublevels; C++ implementation of custom UI widgets; and level streaming.

Now after having spent ridiculous number of hours on it over the past five days, I've spent all afternoon on this write-up. Time to call it a wrap. Thanks for reading, and if you have a chance to try out the game, let me know what you think.

No comments:

Post a Comment