Friday Rewind #2: Killing old features and improving melee combat

22.3.2019 - Jussi Kemppainen

This friday, I will be musing about Killing our Darlings

 

Farewell to Features

 

Now that the game is nearly feature complete we have a better idea of how everything fits together. However, this is not always pleasant. In the last couple of weeks I have removed some features from the game. Features we spent weeks, months polishing and fine tuning to near perfection. But in the end, they had to go!

 

Carrying items

We spent a long time on developing carry-able items. We had to make sure the items do not fall out of the navmesh and that they are always rewindable while being held. Damage needed to register constantly too.

But they were not fun. Picking up barrels of oil just to lose all skills because the player’s hands were tied was never fun. Also, carrying the barrel to the perfect spot for ambushing enemies was impossible. You had to physically walk in the middle of the battleground in order to do that.

It is possible to kick the barrel, hoping it will land in the correct spot. But this is really limited in range.

So, our solution was to cut the feature completely! Remove all carry functionality and just make the barrels and bear traps function as grenades. You can now pick them up and *puff* they magically disappear into your pockets. Then you can lob them inhumanly far at will! You can only carry one of each type of barrel at once though.

Placing an explosive barrel next to an unsuspecting enemy unit is now rewarding and fun.

Arrow pickups and reloading

In our efforts to make our crossbows less effective, we introduced limited amount of arrows for the player. They would need to pickup the arrows from the bodies of fallen enemies and manually reload after each shot. Also, you needed to equip the correct weapon, so for melee you needed to switch to the sword and for ranged you needed to switch to the crossbow.

This all sounded GREAT in theory, but after implementing everything using the crossbow turned out to be a tedious task. So, after having the feature in for 3 months, it was time to let it go and just make a longer cool-down period for ranged skills and remove some damage from the crossbow bolts. The game now plays more fluently and there is no need for all that micromanagement.

We did leave in the arrows that get stuck on enemies though. It looks so cool.

 

Aimed Melee Attacks

For 99% of the production, our weapon aiming was handled by selecting a direction of attack and hoping an enemy was in that fan-shaped area at the correct time. This was OK for us and it forced you to think carefully about the placement of enemies in both space and time to land that perfect shot. For skills with a narrow width, it was super tedious. It was really hard to make the hit connect and multiple tries had to be done in order for the enemy to happen to walk to the correct spot for impact.

I had been mulling over changing this but did not take any action until now. So, I went in and changed all but one cone targeted skills to direct target selection skills. Now all it takes for the hit to land is that the enemy is at range and unable to block. When before you eventually got the same result after assigning the attack command with different aims for maybe dozens of times, now you only need to perform the attack once. Then you can focus on the things that really matter: the synchronization of your characters and the timing of your actions.

As a cherry on top, we also added the functionality for chaining actions, so now you can click on a far away enemy unit and your character will walk to it and perform the attack. This functionality is closer to the turn-based norm of attacking that we were lacking before when you first had to walk really close and then attack an area instead of a target.

Simply clicking on an enemy in walk / run mode will prompt chained move and attack actions.  Standard stuff, but because of our timeline based game-play it took us a while to figure out how to best do it. 3 years to be exact…

The same chained action is now used for items like pickups and levers and such, so you do not need to manually walk next to them anymore. These changes, along with another new ability of being able to click anywhere on screen and have the character walk to the nearest possible spot, and our recent performance optimizations make the game feel so much more smoother.

 

Friday Rewind #1: Optimization and art updates

15.3.2019 - HP Noronen

 

Hi all!

It’s time to introduce the Friday Rewind posts.

Friday Rewind is a weekly post about some of the progress we have made lately. Our aim is to keep on publishing Friday Rewind on each Friday. In addition to Friday Rewinds we are also planning to publish some more specific posts on individual topics.

 

 

Performance optimizations

 

Last week (like the previous couple of weeks) we’ve focused strongly on performance optimization. The current aim has been to reach a level of performance that is very close to what we should have on the release version as well. On a higher level, there were a few major challenges and then just a pile of more general optimization that were done.

First of all, there was clearly a need for overall performance improvement that would help the game to run on lower-end equipment as well. Then again, even with high-end computers there was some performance spiking that made the gameplay experience far from optimal. We focused on both of these things and the performance is now reasonable on mid-level equipment, and most of the spiking has been now dealt with.

A few of the most important fixes included:

Performance hiccups with the vegetation system

One of the things that we noticed were strange slowdowns when turning the camera. This was tracked to Vegetation Studio, which is a plugin that provides us more control and improved performance on vegetation compared to Unity’s default implementation. However, it turned out there’s a silly feature that was creating new colliders on runtime and setting them up, even though in our case we had already built those before. It was a bit hard to find the issue, but disabling unnecessary generation caused a dramatic improvement on performance spikes.

Shader loading spikes

In Unity, the default behavior is to not prewarm shaders before you need them. This is mostly to ensure that we don’t push tons of shader variants into memory, as there’s most likely a pile of them that we don’t need. However, when a shader is loaded for use for the first time, it’ll have a performance hit. In many cases this was actually quite a big hit, so big that it was one of the main sources for performance spikes. Unity supports a thing called shader variant collections, which would allow you to warmup specific set of the shaders early. However, its collection functionality didn’t seem able to collect all the variants that we were using, and it seemed very hard to track which ones were still loaded on runtime. Due to that, we ended up having to warmup all of the included shaders early on. It is not the most effective way to use GPU memory, but it helped a lot with performance for now. This is something we might still revisit during development.

Pooling spikes

Instantiating new objects on runtime can be heavy for performance and cause spikes. For that, we have had a pooling system in place for quite a while. To populate the pool early on, we have used a manual configuration for some common items and also a possibility for scripts to dynamically register something into the pool at the start of a level. However, in case of manual configurations, there was considerable variation in the amount needed between levels, and in some cases we ran out of items in the pool. This was especially true in, for example, the first level, with tons of fire and explosions. We improved our pooling system to be able to record which pools we had to extend when playing through the level and create level specific configurations automatically based on that. That is now in use in some of the levels, and is clearly helping with some of the spikes.

Memory management improvements

When working with Unity, memory management is, in large part, about taking care of garbage. As C# has a garbage collector that takes care of objects from which memory is to be released, it means that reserving and releasing such memory can have a high cost, showing up as performance spikes caused by the garbage collector. This part has been a bit painful for us, as we need to constantly keep recording and freeing snapshots of the game state for rewinding mechanics. However, we were able to tackle a massive number of those issues. I’m not going to delve too in-depth into what we did here, but maybe I will tell more about it in a special blog post later on.

 

UI Improvement: Quick examination box

 

In the current phase of the development, we are very actively looking for improvements on usability and user interface. One of the things that we have been looking at, is to include more detailed information about enemies, characters and other damageable entities in a way that it would not clutter the game screen.

For this purpose, we went through how pile of the other great games have dealt with it and decided that we should aim for something similar to how Divinity Original Sin 2 does it.

On the top of the screen you can see our new quick examination, giving summarized information of the entity under your mouse cursor. The quick examination box includes the main information that you’d want to see during the combat, such as health and active status effects.

On the screenshot, you can also still see the old indicators for the health and enemy name. You can easily guess what kind of mess it would have been if we would have tried to squeeze status effect information there as well!

In near future we are going to work on reducing some of that information as well. At least the overhead health bar has heard it’s death sentence said aloud already.

 

Art updates

 

We now are in a happy place where it is also possible to plug in some of the features we have had planned for ever but never actually finished.

Depth of field and foreground vignetting finally work. The focus stays locked to the active camera target and the black foreground vignette moves to an optimal position based on camera distance from the target. The screenshot is our first taste of the focusing in use. After seeing that we also added distance based aperture control!

Combat stances. Characters who are in combat now look the part. They crouch down a bit and move in a more balanced, ready to strike way. This helps differentiating between characters that are hostile and ones that are not without having to resort to UI indicators.

 

 

 

 

The Story of The Story

26.2.2019 - Joel Sammallahti



Some words from the writer

The development of Iron Danger is proceeding in an equal combination of fits and starts on the one hand, and leaps and bounds on the other. From the writer’s point of view, it’s an interesting time, as story beats and dialogue written months ago are finally seeing the light of the screen. All the while, I’m going back to those earlier pieces of writing, updating them to conform to changes in the game’s mechanics, level design, characters, enemy roster, and so on: the script is constantly in flux. This is an interesting aspect of game writing: nothing is set in stone before the game is actually finished and shipped, but then again, without a solid script, there’s no way to make progress on the actual levels in such a story-driven game. So I though this week we could have a look at the process of writing the story that we started building our actual levels on.

 

It Starts With a Secret Ingredient

When I first started working on Iron Danger, I talked with our lead designer about the story, and he gave me the kernel of it. He had been planning the game for a while, and wanted the story to have real emotional resonance, not just one event after another. His insight was that to guide our writing and design in a direction that would produce that resonance, the story should have an underlying metaphorical level: we should treat the story as an allegory of an inherently resonating core metaphor, like a symbolist painting or poem. I thought that was a brilliant approach, and we agreed immediately to construct the story on his core metaphor. We would not make the core metaphor explicit, but its dynamics would provide us with a foundation, on which to construct a coherent story and game experience. The events of the game and the supporting characters, seen from the point of view of our heroine, would symbolize experiences and forces, respectively, relating to this core metaphor.* What a kooky, romantic way to write a game!

 

 

 

Concept to Outline

The core metaphor provides us with an idea. But ideas are cheap, as any writer will go out of their way to tell you. So, the next step was to turn that idea into the outline of a story. For this purpose, I wrote up a sequence of major events over the course of the game, in a table with one column for gameplay events, and a second one for the underlying meta-level meaning. This table went through a number of revisions, until I was happy with the logic and structure of both sides. The meta-level was instrumental in making the surface-level story work: whenever I was in doubt about an event, or some element seemed off, I looked at the meta-level meaning, and used the logic of that side to figure out how to fix the surface-level problem.

When I was happy with my table, I turned it into a 3-page prose synopsis, divided into chapters. We dug into this synopsis with the lead designer and other members of the team, seeing how it could be improved, and translating it into an idea of the kinds of game content we would need. If I had invented a character or a place, someone was going to have to turn that into a game asset, after all. And if I had written an event, say “Kipuna collapses from pain”, that implied another entry on our coders’ and animators’ checklists. Based on such considerations, we moved some of the characters and events around, fusing or removing extraneous ones, and tightening the whole skein a notch. Throughout it all, we kept the meta-level story in mind, to make sure we didn’t lose sight of the emotional core of the game.

 

Scenic Route

Once we had a good story synopsis, it was time to further refine that into a list of actual scenes. We think of movies consisting of scenes, but games, of course, are made of levels. Right? Well, the approach we took was that from the story point of view, a level would consist of one or more gameplay scenes, interspersed by shorter, story-focused scenes that would just advance the narrative instead of serving up actual gameplay.

I went through the prose outline, splitting it up into scene-sized chunks. These I labeled either cutscenes, in which the player would more or less passively watch a short presentation of information, gameplay scenes, the meat and potatoes of actually running around, fighting enemies, and solving puzzles, and finally, interactive cutscenes in which the player would control the main character in exactly the same way as in core gameplay, but with the focus on dialogue. These were further arranged into levels, sequences of scenes that would carry from one to the next seamlessly, each level separated from the next by a cut implying the passing of time.

The spreadsheet containing all this became one of our main tools for managing the production, with required assets listed for each scene, and each one assigned to a specific level designer. Although we all collaborate on each other’s levels, one person finally bears the responsibility of bringing the level to completion and making sure it hangs together. (Yes, I’m one of the level designers too, as are the lead designer, the producer, and the lead concept artist; nobody wears just one hat in our team.)

 

Two Steps Forward, One Giant Leap Back

Of course, no big project—even a moderately big one like ours—proceeds from point A to B in a straight line. Time and time again, I find myself going back to the story outline with revisions, and small changes to our level spreadsheet are always ongoing. That’s how it should be, too! A game isn’t a piece of writing, and its story isn’t told when it’s written down: it’s only when we’re actually playing what we’ve built that we can figure out what really works and what doesn’t, and so we jump back frequently and make the changes to the story that our experience with the game, half-finished as it is, tells us are needed. I’ll write another post about that, later! Now, I’ve got to fix some dialogue to take out references to an enemy we replaced with another one…

 

 

*So… what is the core metaphor? It doesn’t matter. If we’ve succeeded, the story will be entertaining and evocative, and if not, knowing would in no improve it. It’s nothing unique—on the contrary, it’s almost universal—and once you know it’s there, you can probably guess when you’ve played the game, if we’ve done our jobs right.