A technical analysis of the graphics rendering in Cities: Skylines 2 has identified the reason why the performance is just so poor. Put simply, the game is trying to draw the cityscapes using a shocking number of polygons, with few systems in place to reduce the amount when it's not needed. It's not something that should be happening in a modern game but the recent breakdown also suggests changes within Unity are partly to blame, too.
Before the game even came out, developer Colossal Order issued a warning to potential customers that the performance of Cities: Skylines 2 had "not achieved the benchmark we targeted."
And when the city management sequel finally appeared, it turned out the dev wasn't kidding and the only way to get any semblance of a decent frame rate was to whack most of the graphics settings down to low or completely off. The first patch for the game helped matters a bit but the fact remains that, as a simulation-management game, it really shouldn't be as GPU-dependent as it is.
I learned the full answer to that puzzle over the weekend, via a short Reddit post. It contains two things: A link to a technical analysis of the game, involving a spot of decompiling and rendering software tools, and an excellent discussion of the findings. The breakdown was carried out by software developer Paavo Huhtala, who explored the game's inner workings with a fine toothcomb.
It's a long and dense read, especially if you don't know much about rendering, but the primary issue is that the cityscapes are being drawn using way too many polygons. And I mean by multiple orders of magnitude too many. How do 25,000 vertices (corners of a triangle) sound for a simple clothesline model?
If you need a point of reference, take the clothing models used in Cyberpunk 2077. Some of them use an enormous number of polygons and I've seen one with as many as 29,500. But that's triangles and these will share corners, as they're 'stitched' together. The actual number of vertices for that jacket could be as low as 8,000.
There's so much going on in the Cities: Skylines 2 engine is making nearly 7,000 draw calls and over 50,000 API calls (requests made by the game, via DirectX) in a single frame. Now those figures by themselves, and set in no context don't mean very much, but they're both enormous in general and indicative of the game asking far too much of the GPU.
For example, taking a random scene in Cyberpunk 2077's cityscape shows fewer than 10,000 API calls are required to render the frame. Now, one can't directly compare these two games as they are so very different, and city-sim games are likely to be making more calls than any shooter, as the world changes so much and fills up with lots of interacting models. But even so, 50,000 is…well, a lot!
Normally that many calls would make a game highly CPU-bound, but not so with Cities: Skylines 2. That's because there are yet more problems that just utterly grind down the GPU. Many of the high polygon models used have no so-called LOD (level of detail) versions.
These are simplified versions of the original objects, built from fewer triangles, and get used when the item is far from the camera. In other words, there's no point in keeping all of the intricate details when you can't see them.
Remember that 29,500 polygon jacket I mentioned earlier? It's never really used in the actual game, as LOD versions of this scale that amount right down. When it's being viewed from far away, the item of clothing just gets represented by a handful of triangles, and you can't tell because it's nothing more than a few pixels on the monitor.
The developers openly admitted this was causing performance issues and that it would be resolved in time. Apparently, the decision to use high polygon count models will "become relevant in the future of the project," whatever that means.
For the frame analysis, Huhtala noted that 36 million triangles had to be processed for multiple rendering passes. While a lot of these aren't visible on screen, it's still an excessively high number and would only get larger as the city expands during the gameplay.
It gets worse, though. It seems that Cities: Skylines 2 doesn't appear to cull objects that aren't visible particularly well and combined with the method used for creating shadows (four separate rendering passes just for shadows), a huge amount of time is wasted on processing data that's completely unnecessary. Nearly three quarters of all the draw calls and half the frame time in the analysis were for just doing the shadows!
This is why the game performs so much better when you set the detail levels to low, disable shadows, and anything else that relies on geometry. So it would appear that the developers just made a real mess of things and that they should be held entirely responsible for it all, shouldn't they? Well, perhaps not.
Huhtala's analysis goes further than just examining a frame of rendering. Using a decompiling tool to peek inside how the game was utilising Unity (the engine package used to create the game) highlights a number of problems that were somewhat outside of the developers' hands.
Cities: Skylines 2 appears to make heavy use of two major features of Unity: DOTS and HDRP. The former is a complex but powerful collection of software packages that, in theory, enable games to be hugely intricate and rich in object interaction; the latter is the engine's high definition rendering pipeline and is required if you want to employ all of the latest graphics wizardry in your game.
You don't really need to understand what they do, though, as that's not really the issue. Colossal Order began work on Skylines 2 way back in 2018, quite a while before DOTS reached a public release. Even HDRP wasn't fully ready then or certainly nothing like its current status. Huhtala suggests the devs had to write out a lot of code themselves, simply because Unity either didn't have what was needed or the status of the new software features required significant handcrafted solutions at that time.
My own take is it looks like the developer was very unfortunate with the timing of how things were changing under the hood of Unity but still made the decision to go down that route, despite knowing that it would have to do a fair amount of coding work to navigate through the system changes.
Perhaps Colossal Order had hoped Unity would have pushed through all the changes quickly, giving it sufficient time to get to grips with it all properly. However, it would seem it just had to 'make do' with what it had and ended up making some poor choices for the rendering techniques.
But regardless of this, the end result is the game runs really badly, having been made by a team that chose a development path that involved using software that wasn't fully ready. Or at the very least, the developers wouldn't have much experience with it, because it was so new.
When it comes to creating games across multiple platforms and genres, Unity is typically the engine of choice for hundreds of thousands of projects. But that doesn't mean it's simple to use and, if anything, it's a pretty complex system as it currently stands. The maker of Unity highlights that if you've been developing games for a long time, switching to DOTS is a big change.
Cities: Skylines 2 may become the game it was intended to be and this will all be forgotten about in time. But right now, it stands as a reminder that making huge, complex games is hard and can go badly wrong if you make the wrong decisions early on.