Optimizing Deep Rock Galactic Survivor for mobile
Adam Axler - Unity
Senior Content Marketing Manager
What does it take to bring a complex PC game to players on mobile? Funday Games’s Deep Rock Galactic: Survivor pairs a bullet heaven loop with Deep Rock Galactic's dwarves, classes, weapons, and digging mechanics. The challenge for porting company Piktiv was managing thousands of simultaneously simulated enemies and environmental components while maintaining a stable frame rate on hardware with a fraction of the GPU, CPU, and memory budget.
Delivering that experience on mobile required reworking the systems whose cost scales with enemy count: pathfinding, physics queries, enemy rendering, damage numbers, and environment rendering. The team also had to fit the game inside a 3 GB iPad, support a device spread that runs from current flagships to years-old Android hardware, and maintain a one-way merge with a PC branch that was still in active development.
We spoke with engineering manager Marcus Ekelund and principal engineer Fredrik Åkerblom about porting Deep Rock Galactic: Survivor to mobile, their custom solutions, and how they optimized performance across a fragmented device landscape.
How did the handoff work between Funday Games and Piktiv?
Marcus Ekelund: We branched off from the PC version while it was still in production, so it hadn’t reached 1.0 when we started the mobile port. The plan was for the mobile version to merge back into the main branch, but we diverged too much during the journey, so we’re still separate in that sense. We merge from PC into mobile, so it goes one way, but it doesn’t go the other way.
There wasn’t a lot of collaboration in terms of what we did technically for the port. For UI and UX, and how to adapt the UI, there was a lot more. It allowed us to be very swift, and because we had branched off, we were able to be very destructive with a lot of the systems they had established – breaking them up and doing something different, because we had different optimization goals in mind.

What were your top technical goals going into the mobile port?
Fredrik Åkerblom: Many of the technical goals we had up front were simply: Can we make this run on mobile at all, and how wide a span of devices can we hit? If you look at Apple products, there isn’t a huge granularity you can actually ship to. There’s the most modern stuff, then a slightly wider category that includes a lot of what’s currently available, and then there’s everything else. You want to hit at least that middle category.
One of the recurring issues for us was that all of those devices have 4 GB of RAM, except for one iPad that has 3 GB. So that became a core technical goal: Can we make it run on this iPad without crashing? We had roughly 1,850 MB to work with, and if we went over that limit, it was game over. A lot of the early work was just getting RAM into line, and after that we could look more at the actual performance of the game on various platforms. Android, on the other hand, has like 9,000 different devices at this point, so making sure everything works there is a science of its own.

Deep Rock Galactic: Survivor | Funday Games
What were the biggest performance bottlenecks you hit moving from PC to mobile hardware, and how did you overcome them?
FÅ: There were a few core systems that really stuck out, and they were the ones with thousands of active objects: Damage numbers, projectiles, the world itself, and the animated 3D enemies.
The damage texts, for example, were originally a GameObject using TextMesh Pro. But when you have a thousand enemies on screen and you throw a grenade at them, all of them now need to show a damage number. The bottleneck is generating the text mesh: Having the font translate your string into something visual.
In the end, we used a regular Unity particle system with a spritesheet of the numbers 0 to 9.
ME: Another example was the pathfinding of all the enemies, which used the built-in NavMesh system on PC. We also had a team of engineers from Unity supporting us, and one of them started working on a solution that used flow field navigation instead. Another engineer built a KD-tree solution to optimize away a lot of the physics queries.
FÅ: With enemy rendering, we have something like a thousand skinned mesh renderers on the screen at the same time, and that doesn’t really work. As it turns out, pretty much all of these enemies have a single animation, so we don’t actually need support for multiple animations.
Instead, this uses a system where each keyframe of the animation is baked into a texture. We go through every frame like that, and then all of them are vertex animated by a shader on the GPU, so there’s practically no CPU cost.
Baking it down to a single static mesh and a texture was a big improvement, and it also lets you do things like GPU instancing, since they’re all technically the same mesh with the same material.

Deep Rock Galactic: Survivor | Funday Games
How do flow fields and KD-trees work under the hood, and what did they replace?
FÅ: The flow field is an inversion of where the cost lies for pathfinding. Usually, when you have 20 or 30 agents pathfinding through an environment, you bake a mesh of that environment and each agent is responsible for its own pathfinding. When you have thousands of them, that becomes a pretty big bottleneck, because the cost tends to scale with the number of agents.
You create a grid over the entire level, then start at your target goal, and all of the tiles around it draw an arrow pointing toward the goal. Go one step out, point the arrows again at the closest thing that already has an arrow, and keep going until you’ve covered the entire field. So instead of costing something per agent, it’s based on the size of the area you want to pathfind inside of.
You can limit that further, too. We calculate based on where the enemies are, so we create a bounding box that contains all enemies plus the player, and we only update the space inside of that.
For spatial queries, we used a KD-tree. If you have a big room and you draw a line down the center of it, you’ve suddenly divided it into two spaces. You create a tree structure that you can query quite easily: Here’s a point and a radius, give me whatever is there.
That could replace a lot of the heavier physics queries, where a grenade has exploded here and I need to find all of the enemies in this circle. I’m not sure it was a perfect fit in the end, because the KD-tree has to be regenerated a lot—the enemies are constantly moving, so the KD-tree has to be rebuilt frequently.

A flow field
How did you approach testing and tuning across mobile devices?
FÅ: One of the earlier things we did was establish a device that we felt the game should be able to run on – a fairly low-tier device where we wanted at least 30 fps.
We built an automatic performance measurement system where we can set up a series of scenarios. We ran a total of six scenarios in Deep Rock Galactic: Survivor. We can build the game specifically in this measurement mode, and as soon as it starts on a device, it enters a biome and runs those six scenarios.
One might be a baseline with the player standing still, then we spawn a thousand enemies moving toward you, or we spawn 500 enemies and equip you with all of these weapons and fire them automatically in all directions. That gives us a bit of a spread of what’s going on, and we measure CPU, GPU, memory – pretty much whatever we can measure. We run it through all of the biomes so we can see whether any biome has specific performance problems.
The Unity Profiler was one of our main tools for CPU performance audits, particularly early on when we were looking for low-hanging fruit and the biggest gains.

Deep Rock Galactic: Survivor | Funday Games
How did Addressables help manage content and memory footprint for mobile?
FÅ: Addressables were an important part of hitting the 3 GB memory limit on iPad. In general, we broke out the things that felt straightforward early on. Different biomes, for example, you’re never in more than one biome at the same time, so you can break out all of those graphical assets and settings.
Addressables introduce asynchronous behavior into something that was previously completely synchronous, and rebuilding an entire system to be asynchronous can be a pretty big architecture challenge, depending on your game. But in this scenario, it was the right fit for us.

Deep Rock Galactic: Survivor | Funday Games
What performance benchmarks have you tracked to measure success for the mobile version?
FÅ: Most of our targets were performance-related: On these models we want to hit 30 fps, on these flagship models we expect 60 fps.
In Deep Rock Galactic: Survivor, whenever you kill a bug, a bunch of blue shiny cubes pop out that you pick up to level up. One of our automatic measurement scenarios spawned around 4,000 of those over 10 seconds, and that was a serious performance hit early on. After we did that initial optimization, it wasn’t measurable anymore.
Optimizing enemy movement and physics also raised the fps floor significantly. That turned into the flow fields, as well as a long chain of Burst jobs – 10 or 15 dependencies long – responsible for moving all the enemies, all outside the regular physics system.
This game procedurally generates its levels, so the ground floor and all the walls are built from individual objects. Since we have a top-down camera at the same angle all the time, we can easily calculate the box where we can see things, gather all of those objects, and send them to the renderer via our own batch draw commands. It was a big improvement for the GPU and for the CPU as well, because sending all of those draw calls individually was a pretty big CPU cost.

Deep Rock Galactic: Survivor | Funday Games
What’s your top tip for developers looking to port their PC game to mobile?
ME: It’s not so much about finding the one silver bullet – it’s always about the collaboration between different systems.
FÅ: The cost of shuffling data in and out of various components really starts to add up once you’re processing thousands of entities every frame. If you can manage your data in such a way that you have all of it in native containers, and you use the same native containers throughout the entire process, you can earn a lot there.
ME: Another takeaway from this project: Say you have a game and you realize once it’s done that you probably should have built it using ECS for Unity, or any of the Data-Oriented Technology Stack (DOTS) systems. You don’t have to do a full conversion of your whole game and rewrite it. We’re only using the Burst compiler and a lot of the native data types.
Deep Rock Galactic: Survivor is available on Steam, on Xbox, on the App Store, and on Google Play. Check out more stories from Unity developers on the Unity Blog and Resource Hub.