How to reduce the size of the project Renpy.

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
User avatar
Posts: 338
Joined: Thu Dec 28, 2017 2:37 pm
Location: Russia

How to reduce the size of the project Renpy.

#1 Post by Andredron » Wed Jul 17, 2019 4:14 pm

I will try to briefly describe how you can significantly reduce the size of the project.

There are 2 ways to reduce the size:

1) File formats change

2) To programmatically register

File formats change.

For maximum compression, with minimal loss of quality, the ffmpeg program will be used. It is a very functional program, but we will need it only as a converter.

All work happens in ff-prompt.bat
Windows only !: To facilitate your actions, make a batch file. If you do not know how to do it, then in the control panel, in the settings of the explorer, uncheck "hide extensions for registered file types". Below I attach a document that describes all the lines that allow to automate the process, just paste one of them into a text file and change the extension to .bat instead of .txt. ... e98699587b

In the meantime, a small instruction on ffmpeg:
Ffmpeg writes its path to the bin folder, this is where the main executable file ffmpeg.exe is located and exactly there you need to drop everything that we need to convert.
-i file - incoming file. His name and extension. I set the standard name and extension, so you can rename everything yourself or use the solution with batch files.
"1.webp" - outgoing file.
"newfiles /" - outgoing, ALREADY EXISTING folder. New folder does not create and swears, if it is not.

It is possible and through online convectors, but they often have the size, the file becomes larger, the image grow dull and the quality is not very good.

Recommended format - webp

Now the most imaginative image format is webp and jpg.

Jpg format does not support a transparent background, which is not suitable for sprites. Therefore, we remain on the format of webp. In most cases, this only increases the size of the image.

Webp. It is not recommended to translate lossy formats * .jpg and similar to lossless webp.
It is easier to convert jpg to png and to webp format.

Lossless: ffmpeg -i 1.png-lossless 1 -compression_level 6 newfiles / 1.webp
Lossless: Remove "-lossless 1" from the code above and append "-qscale float" instead, where instead of float write any number from 0 to 100 depending on the quality you need. 0 - lower (although compared to 0 jpg is not bad and less.)
Audio and sound.
Recommended format - ogg

The mp3 format up to 2017-2018 had some kind of license, that using this format, you had to pay deductions. Now there is no such thing, but the format is already old, and it takes up a lot of places (not to compare with wav but still)
Lossy (Opus): ffmpeg -i 1.mp3 -acodec libopus -vn newfiles / 1.ogg
or (Vorbis): remove "-acodec libopus" from the code above, by default ogg is associated with vorbis
(-vn removes the video channel, if there is one, which allows for even lower weight.)
Recommended format - webm

The format that Renpy supports on PCs and on phones without errors and brakes - webm.
About phones there is but:

1) video sprites on Android are not plowed, only full-screen video launched using $ renpy.movie_cutscene ("some_filename.webm")

2)There must be an audio channel in the video, even if there is silence

3) for Android, it's best to encode .webm with opus / vorbis audio (which is more like) and vp9 video.
For maximum compatibility with android you need the same .webm with the same audio, but with vp8 video.
Video channel - vp8, vp9
Audio channel - opus, vorbis
Container - webm
The greatest losses: ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -acodec libopus 1.webm
Adjustable loss: ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -crf 0 -b: v 0 -acodec libopus 1.webm
The "-crf 0" value can be from 0 to 63, where 0 is the best quality. You can use this parameter if you are targeting a specific quality.
"-b: v 0" value means average flow rate. By writing "1000K" you will have a speed of 1000 kbps per second, by writing "1M" you will have a speed of 1 megabit per second. Recommended if you are targeting a specific video size.
Any of the parameters above can be used both separately and together.

Minimal loss (not recommended due to size): ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -lossless 1 -acodec libvorbis -q 10 1.webm

As an option to work with old videos (mpg), you can do this:
ffmpeg -i 1.mpg 1.mp4 (video is automatically processed by the h264 codec, but mp4 is not very good for renpy)
and then again, but in the properties of the resulting file we look at the average speed, for example, 10 Mbps has turned out, then we are guided by this speed.
ffmpeg -i 1.mpg -vcodec libvpx-vp9 -b: v 10M -acodec libopus 1.webm
Video optimization for Android (maximum performance mode)

Additional programs: ffmpeg

To begin with, at the Ren'Py level we set the parameter "config.hw_video = True" in options.rpy, which includes the hardware video rendering mode.

Next comes the optimization of the video itself.
Using the ffmpeg command line, here is an example of a serious optimization:
ffmpeg -i video.mp4 -vcodec libvpx -b: v 3000k -deadline realtime -cpu-used 2 -vf scale = iw / 1.5: -1 -acodec libopus "video2.webm"
The same, but in the bat file (mass production):
for %% a IN (* .mp4) DO ffmpeg -i "%% a" -vcodec libvpx -b: v 3000k -deadline realtime -cpu-used 2 -vf scale = iw / 1.5: -1 -acodec libopus "% % ~ na2.webm "

And parse all the contents:
-i - incoming video
-vcodec libvpx - video codec. Since we have an android, the most productive will be vp8, that is, libvpx.
-b: v 3000k is the bit rate or relative stream rate. To improve performance, we put either as in youtube (720p = 4000k, 1080p = 8000k), or less.
-deadline realtime - set the video processing mode. Real-time results vary greatly from device to device, but performance increases.
-cpu-used 2 - the complexity of the cpu-decoding video. It can be in the range of values ​​from 0 to 5. Already from the 1st, a performance increase begins and up to 5 at the expense of quality damage.
-vf scale = iw / 1.5: -1 is an argument to scale 1920x1080 to 1280x720 and more along the same lines. Resolution plays a big role in decoding, so if you have a short story in FULL HD, then think twenty times if you want to make a separate version for android, so that the phones do not waste downscaling (video picture reduction)
-acodec libopus - audio codec. You can use libvorbis instead of libopus, but libopus will almost certainly weigh less, and it will provide less playback delay.
Well, the last write the output file - "video2.webm"
To programmatically register

Add resurse in archive.

I will not go into the theory - it is here
Just describe the process in 2 short steps.

1. In the options.rpy file you will need to register the names of the archives you want to create. For example:
build.archive ("images", "all") # Instead of "images" there can be anything.
build.archive ("sounds", "all")
2. When we register archiving, we do it as follows:
build.classify ('game / **. png', 'images') # for images
build.classify ('game / **. jpg', 'images')
build.classify ('game / **. mp3', 'sounds') # for sounds
build.classify ('game / **. ogg', 'sounds')
# Learn more about the signs of the asterisk and how to use it - read the link above.

Similarly, you can create separate archives for the script, for videos and, generally speaking, for everything that your heart desires.
This will not save your game from decompiling, but it will be very easy to make patches for it, in which you can separately add images, change the script or change the music. The user will just need to copy the files with the replacement. =)

1. Do not forget that you must NOT have the lines build.classify ('game /**.**', 'archive')
2. All extensions that are not listed in build.classify will NOT be archived
3. Do not forget to register build.classify ('saves /**.**', None), since there, in addition to saves, are stored constant variables

Layered sprite

It greatly reduces the size of the project, when instead of 1 whole the sprite uses a bunch of small images (base, body, separate nose, separate lips, separate eyes, etc.)

I will not repeat, read the already finished article - viewtopic.php?f=51&t=50764

The authors of the article -
Gardares ( ... 04a6b20780)

Ultraviolet disaster (
I know, I'm writing terribly in English.

I'm writing a Renpy textbook (in Russian). Update 22.06.18

Translating to Russian language

Honest Critique

Post Reply

Who is online

Users browsing this forum: No registered users