2
\$\begingroup\$

I'm currently developing a 2D strategy game, and I've encountered some issues with the game map.

My idea is to use a single 2D image as the strategic map for the game. similar to this (Supremacy 1914) but in a 2D version:

enter image description here

However, I'd like players to be able to zoom in to see the details of the map or zoom out to view the entire map. Therefore, the image might have a high resolution (e.g., 10000x8000).

Now, my concern is that loading the entire image into memory would incur unacceptable memory overhead. One approach I'm considering is to divide this high-resolution image into blocks and only load the blocks within the player's view.

However, there's a drawback to this approach as well. If I need to zoom out to view the entire map, I'd still have to load all the blocks, resulting in excessive memory usage. Alternatively, I could prepare a low-resolution version of the image and load it when viewing the full map, but I'm not sure if this approach is elegant.

Do you have any suggestions? Your help would be greatly appreciated.

\$\endgroup\$
4
  • \$\begingroup\$ 10000px x 8000px x 4byte color depth = 320,000,000 byte = 305 MB. And that's without texture compression. How much system RAM and GPU RAM does your target platform have? \$\endgroup\$
    – Philipp
    Commented Mar 4 at 12:36
  • 2
    \$\begingroup\$ Although you might of course hit some other maximum texture size limit somewhere in your technology stack. But you didn't tell us what technology stack you are using. So answers to your question will be very theoretical and ignore practical limitations or special features that apply to your specific technology choices. \$\endgroup\$
    – Philipp
    Commented Mar 4 at 12:44
  • \$\begingroup\$ What engine are you using? \$\endgroup\$
    – Kevin
    Commented Mar 4 at 17:57
  • \$\begingroup\$ Sorry I forgot to mention the technical details. I'm using Unity, and I'm planning to deploy the game on mainstream PC platforms. \$\endgroup\$
    – NoPyDeal
    Commented Mar 5 at 1:02

3 Answers 3

4
\$\begingroup\$

You can do something similar to what Google Maps does (at least visually):

Have different quality versions of your map. When zoomed out, your entire map loads on low quality (let's say 1920x1080), but because you are zoomed out it looks good.

When zooming in, load only that part of the map in high quality. As an example, when you zoom in on the top-left quarter of the map, it will load a new 1920x1080 texture that only shows the top-left quarter of the map, so the whole map would be 7920x4320, but only one quarter of it would be loaded.

You can have different quality levels, so the more the user zooms in, the more quality is revealed. Dividing the map into quarters was just an example, you might need to come up with a way that best works for your project.

This might require to organise the map into a grid, or something similar, depending on your project. Tt's up to you to decide if you want to show this loading process to the users as they zoom in, or attempt to pre-load sections of the map, which might be more complex to do but have smoother results.

Hopefully this gives you at least some idea on how to proceed.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ The usual term for this technique is "virtual texturing". \$\endgroup\$
    – Philipp
    Commented Mar 4 at 13:14
  • 1
    \$\begingroup\$ Thank you! This is exactly what I was looking for. I tried preparing both a high-resolution and a low-resolution version of the same image, then switching to the low-resolution version when the high-resolution one is scaled down to a certain extent. The effect is very good, and players can't even feel the image switching. \$\endgroup\$
    – NoPyDeal
    Commented Mar 5 at 1:14
1
\$\begingroup\$

Another trick you can use is to compose this map in a shader from lower-resolution inputs.

You could use a signed distance field texture for the territory lines to get crisp vector-like edges even zoomed in tightly without spending a lot of texture memory or juggling different sets of tile textures at different zooms (we used this for the topographic contours on our planet maps on Starlink: Battle for Atlas).

This also makes it easy to control the line thickness, if you want to keep borders from vanishing into hairlines when zoomed out or looking to chunky zoomed in: you can dynamically re-draw them with your desired thickness for the current view.

Then the paper surface can be filled in by tiling "detail maps" that you layer based on the zoom level, fading in more detailed/higher frequency tiling when you zoom in, and mipping away as you zoom out.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you, your answer is very inspiring to me. I always hope to achieve some exquisite effects using shaders, but I'm not very good at it. I think using shaders is too difficult for me, but this gives me more motivation to learn shaders, lol. \$\endgroup\$
    – NoPyDeal
    Commented Mar 5 at 1:28
  • 1
    \$\begingroup\$ You can always dip your toe in here and there. You don't have to be a shader wizard to get cool effects or have fun doing it. 😁 \$\endgroup\$
    – DMGregory
    Commented Mar 5 at 2:34
0
\$\begingroup\$

I personally dont think you need to worry, you can split it into smaller images, but the main reason is that even a high res image probably wont take up that much.

From google:

A standard 32-bit color depth (8 bits per channel for red, green, blue, and alpha) would require approximately 8,100 kilobytes (KB) of VRAM for a 1920x1080 resolution image.

8MB for a 1080p image is really not a lot, if we round 1080 to 1000 and 1920 to 2000, 1000 x 10 = 10000, 2000 x 10 = 20000, and 8 x 10 = 80, that means an image with a size of 20000 x 10000 would only take up about 80MB, not as much as you'd think. If you're still worried splitting them up into chunks and loading/unloading could also help.

The main reason modern games use so much VRAM, is because they are loading loads of textures for all the different parts of the game. Just one high res texture shouldn't effect it much.

\$\endgroup\$
6
  • \$\begingroup\$ Thank you, your answer is very helpful to me. As you said, I suddenly realized that loading a 40MB image on PC doesn't have much impact on performance. Maybe it's because I previously tested my project on a browser. Would loading high-resolution images on a browser cause performance issues? \$\endgroup\$
    – NoPyDeal
    Commented Mar 5 at 1:22
  • \$\begingroup\$ @NoPyDeal It might, I'm not sure, however if you're looking to release this game on a browser, you are going to need to heavily optimize a game like this. You would probably be better off releasing it as a standalone game but its up to you. \$\endgroup\$
    – Pow
    Commented Mar 5 at 10:01
  • \$\begingroup\$ A 40MB map on a browser forces users to fetch as well each time 40MB. Depending on their internetspeed that can be anything between a few seconds to a couple of minutes \$\endgroup\$
    – Zibelas
    Commented Mar 5 at 12:04
  • \$\begingroup\$ @Zibelas that's a good point, however you could probably implement a loading screen to solve that issue. Compression could also help, or you could perhaps even look into rendering vector art. Another method could be limiting the zoom, meaning you can reduce quality but noone would be able to tell that easily. \$\endgroup\$
    – Pow
    Commented Mar 5 at 15:48
  • 1
    \$\begingroup\$ Thank you. Indeed, I hadn't considered the browser-related issues. Optimizing for smooth performance in a browser is a challenge. Treating it as a standalone game is indeed a better choice. Thank you for your advice, it has been very helpful. \$\endgroup\$
    – NoPyDeal
    Commented Mar 6 at 5:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .