Originally written in Russian and published in March 2019. This is an English translation of that post.
I've been slowly trying to figure out how my favourite game studio actually works — pulling together what I've learned from digging through their source files, reading interviews, and piecing their pipelines back together.
I'm a 3D guy, so I'll mostly be talking about the things that matter to me: models and textures.
The story is split into several parts, because the material adds up. This is a technical, illustrated reverse-engineering scrapbook aimed at understanding the 3D side of game development — it's unlikely to mean much to anyone outside the field.
Let's go.
I recently realised that the only method that really works for me is "look at the original and turn it over in your hands." I'd been picking up scraps of information here and there about polycounts and what UV layouts are supposed to look like. There are standards and conventions, sure, but those are a general direction of travel — what I wanted was one specific studio's specific approach.
So I took Dishonored 2, a game I've played to death, and started looking for a way to get its source assets into an editor.

The game's local folder contains files with a .resources extension. Sadly, no standard archiver will open them, so it's time to Google.
Half an hour of Googling leads first to forums, then to a set of tools.
Luigi Auriemma wrote a piece of software called QuickBMS which — with a helper script that tells it which game the files belong to — unpacks *.resources into a normal folder. Once everything is unpacked you're left with the structure the engine (a heavily reworked idTech5) feeds its assets from.
Out of all that, two things interested me: models and textures. Models sit under the .bmodel and .bmd6model extensions, textures under .bimage7. Naturally, the models wouldn't open in any 3D package, and the textures wouldn't load in Photoshop.
More Googling turns up another set of gadgets to dig deeper with. On the XeNTaX forums, a user going by volfin wrote a script that converts .bimage7 into plain old .dds, and attached a Blender importer for .bmodel and .bmd6model (oh gods). Download, install, convert.
.dds isn't always easy to open either, so I had to track down a dedicated Photoshop plugin, after which CC 2019 graciously agreed to open the textures. Funny enough, the plugin was written at Intel.

With the Blender plugin installed, importing a model gets you something like this.

Not bad — this is definitely workable, but first let's move it somewhere less painful. Max, for instance.
We find every texture bound to the object by name, push the model across via .fbx, and voilà.

The asset comes in two parts: the carriage and the space bar are animated, the rest is static, but both models share a common texture set. Textures first:

A perfectly ordinary PBR set: first ao (ambient occlusion), then d (diffuse), plus separate g (glossiness), mt (metalness), and a normal map n that looks distinctly odd. I converted them all to JPG for convenience.
Assembled in Marmoset:

Not far off what the model's author, Eric Pira, shows on ArtStation — his texture quality is just higher; I'd guess he went to 2048 for the portfolio version.
In the original, diffuse and normal are 1024, AO and metalness 256, gloss 512. A wild spread — they squeezed wherever they could. It's not a hugely important prop, though it does catch the eye and you can interact with it.
Now the model.
Time to hug it and cry a little.


Total polycount is 6,449 triangles, 7,155 vertices. This is a relatively large object in-game, so you'd expect it to be reasonably detailed.

The UVs are laid out like this:

The empty space in the top right is for the carriage and space bar — the second half of this composite model.
The "exploded" view looks roughly like this:

They clearly economised everywhere: the "cylinders" under the keys are actually prisms. Elsewhere, though, even small details were solved with geometry rather than texture or normal maps — these rolls and thickenings, for example.

Look closely and you'll see the rear roll has half the polygons. Makes sense: it's almost entirely hidden from the player and not especially important, so it gets cut.

Some principles are getting clearer, but the triangulated mesh melts my brain. I've modelled in quads my whole life and staring at a triangulated model feels deeply wrong. Of course, that's an engine requirement — and since we're pulling models out of the engine, the engine's version is what we see.
Let's try to improve the display using the polyquad script for 3ds Max. It works beautifully on triangulated meshes generated by an automatic algorithm.
Breathing is much easier now.




An interesting detail is how the interiors of some cylinders are handled. All perfectly legal, but an unexpected solution to my eyes.

Some places are solved head-on: one chunk of geometry simply wedged into another.


Hard edges are used almost everywhere on the model, smoothed over by the normal map.
Right, that model's figured out. Now I need to gather statistics across different props — which is what part two is for.
Part 2
After that first win with the model, a few questions were left untouched: what does the emissive map look like, how is glass handled, what polycount is appropriate for small props, how are their textures solved, and what does something genuinely huge look like? That's what this part is about.
Let's start easy — with a saucepan!
The game has a range of small props: cups, bottles, glasses, and of course a kitchen full of stuff. We'll use it to work out "how it's made and what it costs."
Find the assets whose names start with the codeword stove — there aren't many.

All of these models use a single texture set — here it is:

The exception is the food stuffed inside two of the pots; those are separate models. Find the food texture and all is well.

I found vegetables and fish. The vegetables are a set; the fish is reused in at least two other models, maybe more. Convenient — no need to hammer players' GPUs with textures.

For scale: the main cookware set's pixel dimensions match the typewriter from last time — 1024 max, dropping to 256 on the secondary maps. But take the vegetables, for example, and their diffuse and normal start at 256 pixels. The smallest (AO and metalness) are 64 pixels.
SIXTY-FOUR PIXELS.
Seems you can relax a bit among these mighty pixels and stop worrying about Substance's 8192 support. Yes, the model is very small — but if a 64px square is enough for a AAA project, that's good enough for me.

Obviously there are 4096 textures too: large objects, characters, chunks of buildings. More on that shortly.
What can we say about polycount and how small objects are built? Not that much — there are no great revelations here. The saucepan model is 610 triangles, 311 polygons (after polyquad). The handle, the only protruding part, eats 131 polygons — nearly half the total.


Worth noting the neatly rounded upper rim.
One side effect of studying things this closely is that you start finding mistakes. The saucepan handle, for instance, is clearly visible where it shouldn't be — it pokes through the inside of the wall. Yes, that bug is in the shipped game 🙂

On to the next objects, and then we can close the pot question for good.
The small ones: ladle, fork, spoon. Polycount doesn't exceed 500 triangles; the smallest, the fork, is just 188.

The vat is physically larger in-game than the small handled pots, and its polycount is 1,064 triangles — almost double. You can clearly see the rim on top and two edge loops just below. The rivets on the handles are done with textures.

Which is gradually leading me to the idea that a secondary set-dressing prop you could fit a character's head into shouldn't exceed 1,000 triangles.
Let's call it the "rule of a thousand."

An amusing difference: the small pots have 30 cylinder segments, while the vat — twice their physical size — has only 24. Explained by the limits they had to hit.
Not much to say about the roasting dish: it's the vessel plus a lid. A thousand for the bottom, six hundred for the top. There's a recess on the inner side and a cute little nub on the handle up top.

Under the handle the texture has also gone strangely askew. Another slip.

Quickly on the vegetables, which have a 256px diffuse. It's a "set," so it's relatively heavy at 658 triangles — the interesting part comes when you open the UVs.


The areas circled in red are overlaps for the "cut" vegetables — the potato and carrot have overlapping cut faces. The lettuce leaf separately uses the alpha channel of the original DDS texture. The small UV chunk at the bottom centre is the thickness of the lettuce leaf. God knows why it's there — that area will be transparent in-game anyway.
I think I'm starting to feel out the permissible level of don't-care in modelling and unwrapping.
One for the road from the kitchen: a few in-game screenshots to show how it all actually looks (all on ultra settings at maximum screen size).

Time to look at something more complicated — lamps, for instance.
There are two lamps with slightly different purposes, and therefore different approaches to generating light.
On the left, an exterior lamp you meet on the street in a dark mission; on the right, an office lamp, more for interior set dressing. Both have a 1024 main diffuse texture.

You can already tell from the set that the right-hand one uses an emission map (self-illumination, 1) and a transparency map (2), while the left lamp has nothing of the sort — but does have a second micro-set for the blue glass bulb inside.


On top of that, the lamp has a separate reflection map (r) complementing the metalness map (mt). The grey value on the metal in the glowing glass parts sits at 127, and on the white glowing bulb it's 64. To make sense of it, we need to see it in-game. Grab the drill.



Now it's clearer where the self-illuminating parts are and how they work. Alongside the textures, an actual engine light source is used from time to time — clearly visible from the shadows and the light cone in the next screenshot. That wasn't present in the other, brighter scene.

Funny detail: objects the player can interact with (pick up or pocket) cast no shadows.

Back to the model.
The same ~1,100 triangles, more odd mesh quirks and bits of geometry poking through. Rather than working out what the mount should look like when the lamp sits on a table, they just made it solid. The don't-care level keeps climbing.


So what about the second lamp, and why does it have no emissive maps? Turns out it glows differently in-game.

Look closely and there's a small cloud of hot air rising around the glowing part, adding a heat-haze effect. The light is a bit brighter too. I suspect this asset has an extra FX layer set up inside the engine and not visible in a 3D editor. The emitter lives there, and that's the light we see in-game. So the textures are needed purely for the off state — hence no emission maps.
The model is complex, built from cylinders, so it's 3,590 triangles.

Interesting UV cuts. The reflector petals all use the same piece of texture, but rotated slightly relative to each other so the tiling doesn't catch the eye. The topmost "disc" has more polygons than those below it. The base is unwrapped into a straight strip, which makes sense. The whole layout is built around the fact that the player looks at this lamp from above — those parts get more texture space than the lower ones.

Let's look at the big objects.
Statues! Huge, beautiful, and you only meet them a handful of times in the game, but they stick with you. You can see immediately that nobody was economising here 🙂

7,404 triangles on the lion, 5,851 on the octopus; diffuse and normal at 4096, with AO the smallest at 1024. The mesh is a thing of beauty.


Both models are the work of Yannick Gombart, who is unhinged in the best possible way. Both pieces are on ArtStation if you want to look at something lovely while I keep muttering.
Landmark assets, the kind that stay with you, are made very carefully — so there's not much to pick at here.
The octopus head is symmetrical, and the UV map once again fits the unfittable, squeezing everything it can out of its allotted 2048×4096.

Almost all the tentacles sit in one zone taking up a good half of the space. Smart work.

The lion is unwrapped by character-art conventions, with a fairly even polygon flow. A gorgeous asset — no optimisation tricks, no fuss; Yannick used all 7.5k polys and enjoyed himself.


Gorgeous.


The octopus has no metalness map, which shows in the reduced specular response.
And that's about all there is to say.
