Configuring asset/atlas sizes, game.project and defOS

Preamble: I have very little experience with rendering pipelines so please assume minimal understanding on the topic.

I have all my assets drawn for 4k resolution. At the moment I only plan to release on desktops and I’m using DefOS to either select fullscreen with native resolution or windowed with whatever resolution (this is what I use for dev - a 720p window). My question is what is the best practice for the settings in game.projects, atlases and assets: should I keep everything at 4k and just let defOS set the correct target resolution? Is there anything else I need to thing about from performance perspective, given most people will probably not use 4k resolution to play the game (although I admit my knowledge on the market of what people use as their native resolution is a bit old).

Any advice, pointers to things to read, would be very appreciated.

To add some flavour, this is kind of a continuation of Window resize/set_view_size issue:

I’ve narrowed down to what I believe is causing the inability to resize the window: if the game.project has a height or width that is higher than a drawable height or width area on the screen, it seems to prevent the resize from working.

This might stem from my misunderstanding of what game.project width and height are meant to be - originally I set it to 4k since that is what my art assets are and then wanted to use DefOS to resize the window to a manageable size (like 720p). As mentioned in the previous topic - it did not work. I ended up having to set the height/width to a quarter and scale all the assets accordingly, then still resizing to 720p via DefOS - which works.

My question as above is what the correct workflow should be and is the resize issue a bug or just me not understanding the intricacies of window sizing and rendering?

In case it’s important, I develop on Ubuntu.

Reposting some comments from Discord and I expanded them as requested on Discord.

one thing that matters in your situation is mipmaps / if you have them enabled / if you adjust their bias within the fragment shader when drawing
you can reduce the size of your assets via texture profiles by selecting some folders / specific atlases (texture profiles are most specific first most broad last) and setting their max atlas size, so typically on mobile I might set a max atlas size of 1024 or 2048 and that will resize your 4k assets for you when you make those target builds - you can select per target settings in a single texture profile file

Something you must remember about Defold is that it is a 3D hardware accelerated engine and not a raster engine all done on the CPU. This in part means that the default window size doesn’t matter as much. You can have a game that is 800x600 and if it’s maximized on a large screen if you have very high resolution assets they will show up as high resolution assets.

In our premium games we target a resolution of 2732x1536, but in our game.project we have it set to half at 1366x1366. Then when we import assets we generally have them as a child of parent objects which are scaled by half 0.5,0.5,0.5 (always keep your scale uniform unless you have a reason not to) - this can be annoying to some people but it’s the best solution for us and it’s just part of the setup process for our big games. Though we use these resolution targets / game.project display values, it’s only for the sake of simplicity. Like you mention it makes it easier to manage the initial window size, and it also gives us a consistent workflow for designing layouts for our actual target resolution.

Though we target the high resolution, and we have atlases which go up to 4k, we still are careful to not use those sizes when publishing in various places. On Steam and iOS we’re comfortable shipping the full sizes. On Android we set the max to 2048. And on casual portals where we know lots of people use older computers we set the max to 1024. We may set web to only 1024 max as well. This is done through texture profiles, and saves you a lot of time trying to resize assets for various releases. https://defold.com/manuals/texture-profiles/

If I open a released project this is what I have for texture profiles since though you can select target we sometimes have multiple settings for the same target. We’ll eventually update the names for these when we ship this product again.

2021-03-21%2008_08_49-Open%20Assets

Here is one of them open. You want the most specific selections early in the list, and the most general (**) last. If you need to fix order it’s easier to edit the file directly with a text editor. In the case of this file, it’s a generic platform profile where we allow the main menu to be 4096 because we want those assets to have a good first impression, while the rest of the game is more shrunk down. This file has not been updated for basis so it will be a little different when it’s updated but the important thing is it’s what you want to use for multiple assets sizes when shipping.

Mipmaps are a set of extra textures automatically generated from your atlas textures which are displayed by the engine as your assets are scaled in your game relative to their initial scale. They are generally much more useful for 3D games (reduce artifacts in distant textures, improve render performance) than 2D projects. For that reason, we generally disable them completely. But they still have some use if you do want them enabled. Some game designs you for sure don’t want to use them.

440px-Mipmap_Aliasing_Comparison

You can use texture profiles to skip generating mipmaps on specific atlases. You can also disable mipmaps on certain materials by setting a sampler and not selecting mipmaps for it.

So the sprite has a sample defined like

uniform lowp sampler2D texture_sampler;

You use the texture_sampler in your material and set it to not have a mipmap value set in its filter min.

Something useful to be aware about related to mipmaps is Sharp Sprite - RGSS for Defold it can be very useful for 2D projects in making the sprites look good.

Something else important to realize is that your sprites need enough inner padding, empty pixel space around them, to be able to rotate smoothly at the edges. So consider a card game like we make. If we give no inner padding to our games, when we rotate them they will have much more visible artifacts at the sides than if we had some inner empty padding, because without the padding there is no room for smoothing.

If you do want to use mipmaps it’s useful to know about the bias. This is set in for example in the sprite.fp

Instead of

gl_FragColor = texture2D(texture_sampler, var_texcoord0.xy) * tint_pm;

You would have

gl_FragColor = texture2D(texture_sampler, var_texcoord0.xy, bias) * tint_pm;

The bias adjusts which mipmap is used. -1.0 means lower, 0.0 means no change, 1.0 means upper. You can experiment to see if it has a use in your project. It’s faster to omit the bias completely than to set it to 0.0 so leave it off if you don’t have a use for it.

My question as above is what the correct workflow should be and is the resize issue a bug or just me not understanding the intricacies of window sizing and rendering?

Hopefully someone else who knows the technical fact of the window size thing can help answer that.

5 Likes

Thank you very much for such a detailed answer - it’s perfect for me to get started.

Quick follow-up question if you don’t mind - how much of this do you believe I should worry about from the get go and how much I can look into when I’m thinking about distributable size and optimization? I can tell the sprite padding is something I need to be aware of from the get go, since it can impact movement logic (due to different sprite sizes), but from what I can tell the rest is decoupled from any game logic.

I think I figured this one out - if I set window size > drawable area on linux it auto maximizes the window, and maximized windows ignore resize requests. DefOS is helpful here so I just check is_maximized and then toggle_maximized to get the desired effect.

1 Like

how much of this do you believe I should worry about from the get go and how much I can look into when I’m thinking about distributable size and optimization?

Texture profile optimization can be done at the end near release. It is one of the most important things.

You can deal with this just knowing the offset positions of your sprites if you keep them consistent. If you use collections as prefabs then it’s very easy to compose assets with many sprites at various offsets.

Hey Pkeod, thank you for such a thorough explanation, reading it was really insightful!
I’ve got a couple of questions:

-I see no mention of High DPI in your answer, but you do scale your sprites in half. Are those things related?

-Why use inner padding instead of margin or Extrude Borders? AFAIK their uses are the same but padding actually modifies the sprite size and the other options don’t. What are the pros and cons of each?

1 Like

High DPI should be an automatic thing that you mostly don’t have to worry about. You should be able to enable it in game.project with the checkbox and it should just work. If there are situations where it doesn’t work please report here with information about it.

You should do tests to confirm behavior. If you have assets that never rotate then this point isn’t of concern.

I think I tested before and both extrude borders and margin had a different behavior vs inner padding in regards to rotated sprites, but that may be an incorrect recollection.

To be clear, what I’m talking about are images with non-blank image data at the very edge of an image.

The main reason you use extrude borders / margin on their own is to prevent texture bleeding between textures on the same atlas. Especially on lower mipmaps where the atlas as a whole gets more fuzzy. Extrude borders of 2 in general is enough to prevent texture bleeding in most cases. Margin isn’t as specifically useful here since for some assets like tiles margin isn’t enough you need to use extrude borders to prevent tile edge bleeding with the empty space around it.