The Android Update! - Part 2

Mustar riding the green phone robot!

Fluffy- Hi ! Well, we’ve been busy since the last public demo hotfix.

Android Build


An Android build is coming! We’ve been working on it quite heavily.
The first major bottleneck was performance. It doesn’t look like it, but StarSpawn is quite hungry in regards to performance. We have lots of tilemaps, normals, lights, and many cameras rendering to achieve effects such as water reflection etc…
We’ve tested the Android build on a few phones. On the first build we made, we had the following performances:
  • Galaxy A32 5G: Unplayable (Less than 5FPS, crashes out of memory after a few seconds, crashes when trying to decode videos)
  • Xperia 10 IV: Unplayable (Less than 5 FPS, sometime crashes)
  • Nothing Phone 2: 10 to 20 FPS, works but FPS aren’t great and often dips. Less than 10 FPS in rooms with lots of details. Graphical issues with black artifacts.

Of course, this is hardly acceptable so we got to work. Developing on Android really is a rollercoaster. Some things will be fixed and others will break. It’s a test in sanity to be honest.
But through grueling work and using native tools to analyze GPU usage and draw calls, we now got the following:
  • Galaxy A32 5G: 15-25 FPS (Issues with VFX Graph unfortunately. No particles are rendering. Crash on video decode fixed.)
  • Xperia 10 IV: 20-25 FPS.
  • Nothing Phone 2: 25-35 FPS.

But this isn’t quite enough. So we created a new tab in the options menu for quality settings.
What we realized is that ShadowCasters2D take a LOT of processing power. So, on phone, we had to compromise. We’ve added a toggle for you to set it on or off, but by default, we will have ShadowCasters disabled on phone. The graphical changes without ShadowsCasters are minimal, and we adapted the few rooms that needed some tweaks because of that.

We also added a new Render Scale option. If disabling ShadowCasters isn’t enough, you can also lower the render scale. It might look a bit blurry under 50%, but it has a huge impact on performance.

With this, we ended up with the following:
  • Galaxy A32 5G (Shadow Casters OFF, Render Scale 50%) : 30-40 FPS
  • Xperia 10 IV (Shadow Casters OFF, Render Scale 50%): 35-50 FPS
  • Galaxy A56 5G (Shadow Casters OFF, Render Scale 75%): 55-60 FPS
  • Nothing Phone 2 (Shadow Casters OFF, Render Scale 100%): 55-60 FPS
  • Nothing Phone 2 (Shadow Casters ON, Render Scale 75%): 40-50 FPS

Now, that's finally numbers I'm happy about. We also tested a controller through bluetooth on phone, and it works :)
All the performance improvements will also be applied on PC build, of course.
Then, there’s the issue of working on new control inputs. This is a lot of trial and error, and this is subject to change, but right now we have a disposition we’re pretty happy about.


Palette recolor (Again)


We talked previously about palette swaps for sprites. In the previous post, we mentioned using indexed black and white sprites and then using a palette to ‘assign’ each index a given color.
While this worked, in practice, this caused two major issues:
  • Any sprite that we wanted to palette swap, we had to export using a very specific pipeline is Aseprite to get the indexed sprite.
  • With Ses having more and more complicated Aseprite files for the game’s enemies and sprites, it was getting near impossible to be able to use the aforementioned pipeline without it being destructive to his own files.

As such, I had to look for another solution.
I’m not too well versed into HLSL writing, so most of the time, I prefer to use ShaderGraph. This is what the old color palette looked like in our main shader:




What I liked on this graph is that I could just extract an index from the diffuse sprite, which I then use to fetch the corresponding color in the palette. It’s a simple fetching operation,
but ideally the diffuse sprite wouldn’t be indexed. So I switched the operations.
I start with the original sprite in the original colors and replace it with a new alternative palette.
The original color palette is a simple image of a few pixels wide.
Then my idea was that for each pixel I’m trying to draw in the shader with a palette swap enabled sprite I would compare each pixel’s color with each pixel from the original palette.
If I find a match I would then use a new palette to fetch the new color at the same UV relative to the old palette.
In theory this is rather simple. In practice though… ShaderGraph can’t do that.
But what ShaderGraph can do though is have a custom node to write your own HLSL. This is how I created the new node:
This node of course is more than it looks. The subgraph node looks like this:


And really the heart of the graph here, the function that does the color lookup and UV matching, is the FindUVForColor custom node. This is a custom node I wrote in HLSL:
Finally, using pure HLSL I was able to do the loops I needed, and as such a proper lookup.
And the best part is that it uses only the original sprites in their original diffuse color, along with the original palette. No more indexed sprites required. Ses is going to have a field day with this :)

New H Interaction system


We continued to port each interaction over to the new interactive system. Now, not only Rask supports it, but also the PunchShrimp, the Cyclops, the Centipede, and the Cockhugger, with Bonehead nearly complete ! Originally we had planned to space out the art and implementation for different characters between updates but delays from Unity updates and boss development gave plenty of time to work them in sooner. We hope you enjoy the new H Interaction gameplay soon !

Work on the new Meteo Boss


It’s hard to show things here without spoiling too much, but we’ve been hard at work on this one. This will be a long boss which will probably ask you to try a few times to beat it. We had that boss playtested quite a few times on what we have so far, and we found that we tend to overtune the difficulty. This is to be expected though, with us testing the game over and over in development. Once we got most parameters in check though, the boss becomes very interesting and very different than what you encountered in Zennia.


Animated tiles pipeline


One thing I bother Ses about is that I want more animated tiles. Animated tiles improves the feel of the game so much and makes it more alive.
However, in Unity, there isn’t an included pipeline to easily generate animated tiles. You have, for each tile, to create a tile, and assign each frame its own sprite.
For a few tiles, it’s doable, but when you have this…:
Animated background conveyor belts


That’s 10 x 5 tiles to create and assign each 8 frames, or in other words, over 400 frames to drag and drop in editor.
I had to make an automated pipeline for this.
This is where I overrode the original texture imported of Unity and added my own stuff on top of that, adding the last section here.

This allows us to automatically generate and assign animated tiles. I hope that in the future, we’ll have way more animated tiles :)

Audio optimizations


I rewrote the BGMManager a bit to handle intro and loops in a better way. We now have seamless intros and loops for Kohu to work with. I also optimized the loading of these files during a room transition. You shouldn’t have any stuttering anymore when an audio file starts playing.

New fatal hit system


We introduced a new mechanic to the game: Now, when the player gets fatally hit, you don’t get instantly killed. You get a slowdown for a couple seconds, as well as a short invulnerability.
If you get hit again you will die. However, this ‘fatal hit guard’ can be restored even by recovering a single HP. This gives very interesting moments for the player where our testers were frantically trying to reach a health pickup during invulnerability :p


>>> Plans for future builds <<<


Overall, we did a lot of optimization for the game. We thought about how we’ll release the next builds. One issue is that as much as we try, we don’t really have supporter builds. And we want to change that, as thanks for supporting the game’s development.
Here’s how we plan to deploy the builds soon:

  • Public Demo: Updated with the latest QoL and performance boosts. Content will still end right before Meteo’s boss and lead to the demo room.
  • Private Build: Updated, and will have the new Meteo boss with a few new rooms afterwards to play with.
  • Experimental Build: Same as Private Build, but for Android. Since there’s only so many phones we could test the game on, it makes sense for this one to be experimental until we’re sure it works decently enough. :)