Jump to content
  • Advertisement

How I halved apk size

Ruslan Sibgatullin

1802 views

1*u_5yDFEpoTD3ST_bn0dgfQ.jpegOriginally posted on Medium

You coded your game so hard for several months (or even years), your artist made a lot of high-quality assets, and the game is finally ready to be launched. Congratulation! You did a great job. Now take a look at the apk size and be prepared to be scared. What is the size — 60, 70 or even 80 megabytes? As it might be sounds strange to hear (in the era of 128GB smartphones) but I have some bad news — the size it too big.

That’s exactly what happened to me after I’ve finished the game Totem Spirits. In this article I want to share several advises about how to reduce the size of a release apk file and yet not lose the quality.

Please, note, that for development I used quite popular game development engine Libgdx, but tips below should be applicable for other frameworks as well. Moreover, my case is about rather simple 2D game with a lot of sprites (i.e. images), so it might be not that useful for large 3D products.

 

 

 

To keep you motivated to read this article further I want to share the final result:

I managed to halve the apk size — from 64MB to 32.36MB.

Memory management

The very first thing that needs to be done properly is a memory management. You should always have only necessary objects loaded into the memory and release resources once they are not in use. This topic requires a lot of details, so I’d rather cover it in a separate article.

Next, I want to analyze the size of current apk file. As for my game I have four different types of game resources:

1. Intro — the resources for intro screen.

1*sC1w5idpfpfhzGSIL9_E8Q.jpeg

Intro background

Loaded before the game starts, disposed immediately after the loading is done. (~0.5MB)

2. In menu resources — used in menu only (location backgrounds, buttons, etc). Loaded during the intro stage and when a player exits a game level. Disposed during “in game resources” loading. (~7.5MB images + ~5.4MB music)

3. In game resources — used on game levels only (objects, game backgrounds, etc.). Loaded during a game level loading, disposed when a player exits the game level. Note, that those resources are not disposed when a player navigates between levels (~4.5MB images + ~10MB music)

4. Common — used in all three above. Loaded during the intro stage, disposed only once the game is closed. This one also includes fonts. (~1.5MB).

The summed size of all resources is ~30MB, so we can conclude that the size of apk is basically the size of all its assets. The code base is only ~3MB. That’s why I want to focus on the assets in the first place (still, the code will be discussed too).

Images optimization

The first thing to do is to make the size of images smaller while not harming the quality. Fortunately, there are plenty services that offer exactly this. I used this one.

This resulted in 18MB reduction already! Compare the two images below:

1*9A23phO-TVVQN11IBzJYhA.png

Not optimized

1*kmzB4p8v9MNSujGpX1gEPg.png

Optimized

the sizes are 312KB and 76KB respectively, so the optimized image is 4 times smaller! But a human eye can’t notice the difference.

Images combination

You should combine the same images programmatically rather than having almost the same images (especially if they are quite big). Consider the following example:

1*vn0LQGYxKlyEv6GWENs18A.jpeg

Before

1*7q6CTo6Gr1z6CWHvkU_f2A.png

After

1*wqQS_j0RgQbpT7QqzHldNw.png

God of Fire

1*GC097jZ5LGWJIyzscAV8bA.png

God of Water

Rather than having four full-size images with different Gods but same background I have only one big background image and four smaller images of Gods that are then combined programmatically into one image. Although, the reduction is not so big (~2MB) for some cases it can make a difference.

Images format

I consider this as my biggest mistake so far. I had several images without transparency saved in PNG format. The JPG version of those images is 6 times more lightweight! Once I transformed all images without transparency into JPG the apk size became 5MB smaller.

Music optimization

At first the music quality was 256 kbps. Then I reduced it to 128 kbps and saved 5MB more. Still think that tracks can be compressed even more. Please, share in comments if you ever used 64 kbps in your games.

Texture Packs

This item might be a bit Libgdx-specific, although I think similar functionality should exist in other engines as well. Texture pack is a way to organize a bunch of images into one big pack. Then, in code you treat each pack as one unit, so it’s quite handy for memory management. But you should combine images wisely. As for my game, at first I had resources packed quite badly. Then, I separated all transparent and non-transparent images and gained about 5MB more.

Dependencies and Optimal code base

Now let’s see the other side of development process — coding. I will not dive into too many details about the code-writing here (since it deserves separate article as well). But still want to share some general rules that I believe could be applied to any project. The most important thing is to reduce the quantity of 3d party dependencies in the project. Do you really need to add Apache Commons if you use only one method from StringUtils? Or gson if you just don’t like the built-in json functionality? Well, you do not. I used Libgdx as a game development engine and quite happy with it. Quite sure that for the next game I’ll use this engine again. Oh, do I need to say that you should have the code to be written the most optimal way? :) Well, I mentioned it.

Although, the most of the tips I’ve shared here can be applied at the late development stage, some of them (especially, optimization of memory management) should be designed right from the very beginning of a project.

Stay tuned for more programming articles!



4 Comments


Recommended Comments

Always interesting to hear experiences! :) I guess the runtime footprint and the APK size are quite interrelated, did you have any problems on devices from runtime memory use which encouraged you to load resources only when required? Or was it more a pre-emptive measure to prevent problems on smaller devices (difficult to test there are so many!)?

Another good trick with the multiple similar images is to do a 'diff' on them, and then instead of saving the whole image each time, just save the difference. If a lot of the values are the same, the diff will be zero and this will compress well.

Share this comment


Link to comment

Hi lawnjelly! Actually, that way to organize resources loading is one of the "best practices" suggested by libgdx devs. So it is more a pre-emptive measure indeed. But I even tested the game on my old Acer Liquid MT (released 7 years ago) and everything works smoothly :) 

The trick about images diff sounds complicated, have you ever used it in a real project? 

Share this comment


Link to comment

All the time, saving the difference between values rather than an absolute value is one of the most fundamental compression methods. I've used in it images, video, audio, animation data, both as part of my own compression, or as a pre-process before applying other compression (like png). And nearly all compression formats you use everyday will use the idea. :)

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By FlyX
      Hey Gamedev.net Community!
      I am working on a mobile builder game that's already running for 8 years.
      In its early days, the game had a nice content progression until level 30(current max level is 140). With content progression, I mean at what level items unlock in the build menu. However, over the last ~4 years, the previous developer decided to unlock all the content between lvl 1 and level 30 (reasoning that the new content should be available for all players). This results in 1200 ~available items at level 1 and ~3300 items at level 30. Overwhelming players at the start and missing any content progression after level 30(can be reached within a few weeks, while a big part of the community is playing since multiple years).
      But how should this be addressed in a running game with a considerable user base across all levels?
      Internally we have a passionate discussion between moving existing items to later levels(and risking to anger existing players) or just adding new content to later levels(don't address the too much choice issue at the start)
      Since we are kinda stuck in the discussion, it would be nice to hear some external input
      Thanks!
    • By Ewe Tek Min
      Color Fiesta is a collection of best and most addictive color matching games with minimalism graphics and unique game level design that suitable for kids and adult. 

      You can play the best color matching game like Match And Catch, True Color, Color Roulette which are easy to learn and fun to master in one game. As a color matching game lover, you don't need to spend time searching new brain teasers any more. We will give you a ONE-STOP game experience from now on!

      Games you can play in Color Fiesta
      ★★ Match And Catch ★★
      Simply rotate the blocks so that the side of the block that face the falling ball has the same color with the falling ball. Make sure you are reacting fast enough to keep rotating the block to match the color of falling ball.

      ★★ True Color ★★
      There are several options appear on the screen, only tap on the options that the color is match with the text of the option. Stay patient and look carefully before you make your choice!

      ★★ Color Roulette ★★
      The roulette is keep rotating, make sure you only tap on it when the section is match with the color of the pointer! Beware, it's keep speeding up!

      ★★ And many more games ★★
      We will constantly adding new game so that you can keep having fun with us without spending much time search for your favorite games!

      Time and patient is the key for you to complete all levels.

      Please feel free to leave your review or feedback to us @ bigcheeseapp@gmail.com! We'd love to hear from you!


      Download now from Google Play or scan the QR code below

       
      Download now from App Store: Coming Soon...
    • By Eagleman95
      Hi everyone, I release my new game Head Stall Soccer, your goal is to keep the soccer ball over your head without letting it fall.
      I'm relatively new in gamedev so feedback and suggestion are appreciated.
      Here is the link: https://play.google.com/store/apps/details?id=com.EBDev.HeadStallSoccer
    • By Duco van Amstel
      Hello there,
      I'm Duco, a dev working on SpatialOS. I just wanted to let you know that today, following lots of feedback from devs, we launched our new Game Development Kit (GDK) for Unity. It helps you to quickly create, iterate and grow your multiplayer game. Early adopters have already described it as a huge improvement over our previous Unity integration, but I wanted to see what you thought.
      To help with that, you can try out our open-source example FPS, which will give you out-of-the-box access to a 200-player experience and modify it for your own game idea. For questions or help, our developer community will welcome you on both our forums and our Discord server.
      Finally, for those of you who will be coming to Los Angeles for the Unite event at the end of the month, we are holding a Happy Hour event. You will be able to talk with the technical and product leads behind the GDK, and see how it puts the multiplayer game that you have always wanted to build within your reach.

    • By IPnose
      Hi all,
      I'm here to present you my very first Android game, Crystal Mine.
      The principle is very simple, by touching a crystal not enclaved by other crystals, all adjacent crystals of the same color will disappear, the other crystals of the same color (and not enclaved) will also disappear. The goal is to remove a minimum of 80 crystals in less than 8 strokes. I don't know if it's really clear to read like that, but it's much more intuitive when confronted with the gameplay.
      The link on the store: Crystal Mine on Google Play
      A big thanks to all those who will take the time to test it and give me a little feedback.
      See you later!
       



×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!