Jump to content
  • Advertisement

How I halved apk size

Ruslan Sibgatullin

1714 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 EmmersionStudios
      Hi,
      We're currently looking to recruit a programmer to help us build out the remainder of our game, MATCHINO, for Android and iOS. Matchino is a match-3 game, utilizing elements of poker and casino gaming, in real life cities and towns throughout America. Our team is serious about putting out a polished, professional game. While we learn about the development process (it's been an eye-opener thus far), we also receive a portion of the profit share from in-game purchases and ads (using strategies designed to maximize revenue).
      Programming-wise we have the following set up: Facebook to accept player logins and store player save data, working game board mechanics, end-game process, startup screen, loading, menu UIs, and first 20 levels complete. We're gearing up to complete a demo for experience testing and for release within the next 2-3 months.
      We want to move on from this project to develop earth-shattering games, but we knew we needed to start small and gradually work up to that. Everything legal is in order, we're an LLC, we have a website/Facebook presence, contracts, etc. We just need some more help.
      If you're interested please PM or email me at sam.azzarano@emmersionstudios.com (or visit our website at www.emmersionstudios.com)
      Thank you!






    • By leekeechild
      https://play.google.com/store/apps/details?id=com.tileremover_if
       
      Tile remover is the mix of classic bubble shooter and falling down block puzzle. Try to remove
      all tiles from the playground. Colored tiles are falling down one by one in a round and you
      must place them how the same colors should be alongside. If you make a group of tiles [by at
      least 3 tiles] from same color then them will be removed. When you skip more than 1 or 2 rounds
      without making a group then a new line with tiles will appear of the bottom side of playground.
      Have fun!
       
       
    • By Ericjor
      Hello Gamedev users. I am new to this forum, and though I am quite proficient at understanding the basics of just about any form of science, I do not have the natural skill or patience needed to become a great programmer, so I ask that you be patient, and bear with me.
      So, to get to the point, I have thought up a peripheral that can potentially be used for various PC games. Without giving away too many details to those not interested in contributing, I will give as informative an explanation as possible. In theory, it will be activated in intense danger sequences, such as in a FPS firefight, melee combat and fight scenes in medieval style RPG's, etc. The difficulty is not in designing the device, but in implementing the program that would detect these scenes in-game. The software would be for Windows PCs, and made to work with as many games as possible.
      I have some experience with how modding works, and have considered how it could be used alongside currently released games such as Fallout 4, Battlefield, Call of Duty, Elder Scrolls Skyrim etc. However, I simply do not know enough about programming to determine the viability of integrating features into the software that would allow the danger scenes and combat gameplay of already released games to trigger the software to activate the peripheral. 
      Essentially I am wondering if this would this be something that could be integrated? If so, how could these combat sequences be detected by the software? 
      If you are interested and have something important to contribute, I can promise you a copy of the software and option to purchase the peripheral at cost if you would like. Depending on your motivation, I am open to working together. Even if you are not highly experienced, everyone has to learn somewhere.
      Whether or not you are interested, I would be grateful for all the advice you have to offer. So, any ideas for how something like this could be implemented?
       
    • By Zippy1970
      I've created a HTML5 2D canvas game and I'm now ready to take the step and convert it to a native Android (and iOS) app. The game works perfectly fine in any desktop or mobile browser. Animations are fast and smooth.
      After some research, I decided Cordova was the way to go to create native apps for Android and iOS. My first priority is Android, simply because I have an Android phone myself and I don't have a Mac (which apparently is required to build iOS apps).
      I have looked at Cocoon.io and although that might be an even better option than Cordova (since it's actually build on top of Cordova), the thing that made me run from it is the fact that it costs $500 just to remove the "build with Cocoon" splash screen...
      After installing all prerequisites (cordova, Android Studio, nodes.js) building my first APK was easy.
      When I ran my game in the Android emulator, the game was abysmally slow... Testing it on my device yielded the same slow results. After searching the internet, I figured it was because on some devices, an old and slow WebView is used by native apps to display HTML5 content. Still strange since my phone uses Android 7.0.0 and the emulator uses Android 8.0.0...
      I quickly found FastCanvas, a PhoneGap/Cordova plugin that adds a very fast canvas "compatible" rendering surface. But it was last updated in 2013 and after trying to get it to work for almost 16 hours straight, I came to the conclusion there's no way to get this to work with the current version of Cordova.
      I then found CrossWalk-WebView. This too was pretty old and a pain to get it to work with the current version of Cordova. And when I did get it to work, I quickly found out it created a few new problems making my game unplayable (noticeably a strange lag when touching the screen. Not the famous 300ms input lag, but after touching the screen, the entire game would freeze for 200ms-300ms). So I had to give up on Crosswalk as well.
      So now I am at a loss. Can anyone offer me suggestions on how to speed up canvas rendering in Cordova? It's pretty darn frustrating that my HTML5 game is finished and I'm ready for publication, only to find out that's not as easy everyone says it is...
      (BTW, I've posted the same question on a few other forums to reach as many game developers as possible.)
    • By janek29
      Hi, I want to present my game called "Stick Bunny" – arrcade game in which you have to help Bunny to go from one platform to another.   Download from here: https://play.google.com/store/apps/details?id=com.threemgames.stickbunny   Youtube video gameplay:             Funny Bunny wants to go from one platform to another. Use stick and help Bunny. Stick can increase the length. Be careful, if the stick is too long Bunny will be knocked and if it is too short Bunny will fall down.   Try to go as far as you can.   Collect carrots and exchane them for new characters of Bunny. Tap the screen to change size of the stick.   Are you ready to reach 100 platforms or mayby you want to go even farther?   So tap the screen, join platforms with sticks, and collect carrots.   It is FREE!   I am waiting for your comments.   Please, give me feedback. If you notice any bugs please tell me.   Thanks !
×

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!