- Apr 7, 2022
- 24
- 17
EDIT (2023-12-04): Added link to "warpa" RPA tool
EDIT: I'd like to note that this is primarily aimed at introducing tools that allow you to automate builds. It isn't a fully fledged template for doing so. Figured I'd edit this in now before some silly goose misunderstands the point
The default workflow for Ren'py developers is to use the actual Ren'py app to run, test and build their projects. I personally find this to be very frustrating.
There are several tools at our disposal for automating the process of building a Ren'py project - and I'll go over the ones I currently use.
Quick caveat: I primarily develop in a *nix environment and test on Windows. Most of this can be easily translated to Windows - which I presume most Ren'py devs are using. I'll write a follow-up article at some point when I have time to test this process there.
Let's talk about what the normal process is and we'll examine what we can automate away for each step.
Ren'py UI
The standard way of building things in Ren'py looks like this:
There are several options here, the most important being:
- check script/lint
- force recompile
- building archives (part of building distros, but we'll ignore that)
- build distributions
Each one of these steps can be automated away.
Linting
Linting a Ren'py project from the command line is incredibly easy. If you're writing raw .rpy files, all that is needed is:
Replace the path to your game (and possibly your Ren'py install). You may get a number of errors from the "standard" Ren'py files that fail to compile, which you can ignore. I know ignoring stuff is silly, but the tool will hard-fail if you have errors in your actual code.
Recompilation
Compiling the .rpy files to .rpyc is similarly easy, using the same command line:
Similar to the previous part, you will probably get errors based on where Ren'py is installed. I ignore those. I know ignoring stuff is silly, but the tool will hard-fail if you have errors in your actual code.
Building Archives
Now, linting and recompiling is easy and really not all that interesting. Making your project less of a mess for yourself and users, however, is awesome. Content updates and patches can be handled in a much easier way with archives, diffing a large number of files (I'm looking at you, LiL!) would be incredibly annoying. Games that require a full re-download drive me up the wall, even if I'm willing to do it.
Tools that are usable for this purpose that work well:
-
-
-
The standard way requires some changes to "options.rpy" - we'll talk about that quickly and move on to the easily automated tools.
Archives: The Standard Way
The normal way of building archives in Ren'py is to update the build section in "options.rpy".
Specifying "None" means that Ren'py will ignore files of that type. Specifying a name afterwards means that files matching a glob will go into an archive with that name.
The line "build.classify('game/**.png', 'archive')" will ensure that any PNG files dropped into the "game" directory will be packed into an file called "archive.rpa".
In my opinion, this leads to a very messy "game" directory for the developer.
rpatool
rpatool is fairly easy to use. My problem with it is just that I have to install Python.
(edit: unfortunately, some people lack humor, so I must specify that this is a joke.)
Let's say you want to pack images from a "chapter 1" into "chapter1.rpa".
Note that "path-to-chapter1-images" will be included in the file path inside of the archive itself, so if you're working on your game with an organized structure, eg:
You may want to, instead, "cd game/chapter1" and then "rpatool -c ../chapter1.rpa images/".
Totally up to you and how you organize your project.
arpy
arpy is written in Go and has prebuilt releases you can download for Linux, Mac or Windows.
Similar to rpatool, if you want to pack up an image-only "chapter1.rpa", you can run something like:
That ".+\.png" part is a regular expression (regexp), similar to "options.rpy", allows you to specify files by a pattern and skip others.
Building Distributions
For building the project and making a zip you can ship, look no further than
Renkit provides a way to download and use various versions of Ren'py, build your project, and notarize that project for use on MacOS - which is pretty awesome.
We're only interested in `renconstruct` right now, though.
The command to run should look like this:
As you can see, you'll want a "renconstruct.toml" file. This allows you to skip some of the command-line options.
Mine looks like this:
This takes care of building the zip archives of your release.
Tying These Together
Again, as mentioned, I develop on *nix and have CI/CD set up that runs this stuff for me every time I push to my repository. How my CI/CD does this is by running commands I've specified in a configuration file - in this case, we'll look at Make.
A simple one could look like:
Running "make lint" will detect issues in your game via Ren'py's lint, "make build-debug" will handle archives, "make distribute" will handle building a zip that you can give to users.
Again, I want to stress that this post serves as an example. There are more pieces to the puzzle to be figured out, but if this is something that interests you, it's a decent starting point.
Wrapup
Thanks for reading, and I hope that you found something useful here. Happy to answer questions and help in any way I can.
EDIT: I'd like to note that this is primarily aimed at introducing tools that allow you to automate builds. It isn't a fully fledged template for doing so. Figured I'd edit this in now before some silly goose misunderstands the point
The default workflow for Ren'py developers is to use the actual Ren'py app to run, test and build their projects. I personally find this to be very frustrating.
There are several tools at our disposal for automating the process of building a Ren'py project - and I'll go over the ones I currently use.
Quick caveat: I primarily develop in a *nix environment and test on Windows. Most of this can be easily translated to Windows - which I presume most Ren'py devs are using. I'll write a follow-up article at some point when I have time to test this process there.
Let's talk about what the normal process is and we'll examine what we can automate away for each step.
Ren'py UI
The standard way of building things in Ren'py looks like this:
There are several options here, the most important being:
- check script/lint
- force recompile
- building archives (part of building distros, but we'll ignore that)
- build distributions
Each one of these steps can be automated away.
Linting
Linting a Ren'py project from the command line is incredibly easy. If you're writing raw .rpy files, all that is needed is:
Code:
$ /usr/share/renpy/renpy.sh path-to-game/ lint
Recompilation
Compiling the .rpy files to .rpyc is similarly easy, using the same command line:
Code:
$ /usr/share/renpy/renpy.sh --save-dir /tmp/ignore --compile path-to-game/ compile
Building Archives
Now, linting and recompiling is easy and really not all that interesting. Making your project less of a mess for yourself and users, however, is awesome. Content updates and patches can be handled in a much easier way with archives, diffing a large number of files (I'm looking at you, LiL!) would be incredibly annoying. Games that require a full re-download drive me up the wall, even if I'm willing to do it.
Tools that are usable for this purpose that work well:
-
You must be registered to see the links
- a Python-based RPA packer and unpacker-
You must be registered to see the links
- Go RPA packer and unpacker-
You must be registered to see the links
- Rust RPA packer and unpackerThe standard way requires some changes to "options.rpy" - we'll talk about that quickly and move on to the easily automated tools.
Archives: The Standard Way
The normal way of building archives in Ren'py is to update the build section in "options.rpy".
Code:
init python:
build.classify('**~', None)
build.classify('**.bak', None)
build.classify('**/.**', None)
build.classify('**/#**', None)
build.classify('**/thumbs.db', None)
build.classify('game/**.png', 'archive')
build.classify('game/**.jpg', 'archive')
build.documentation('*.html')
build.documentation('*.txt')
The line "build.classify('game/**.png', 'archive')" will ensure that any PNG files dropped into the "game" directory will be packed into an file called "archive.rpa".
In my opinion, this leads to a very messy "game" directory for the developer.
rpatool
rpatool is fairly easy to use. My problem with it is just that I have to install Python.
(edit: unfortunately, some people lack humor, so I must specify that this is a joke.)
Let's say you want to pack images from a "chapter 1" into "chapter1.rpa".
Code:
$ rpatool -c game/chapter1.rpa path-to-chapter1-images/
Code:
/
game/
chapter1/
chapter1.rpy
images/
something.png
Totally up to you and how you organize your project.
arpy
arpy is written in Go and has prebuilt releases you can download for Linux, Mac or Windows.
Similar to rpatool, if you want to pack up an image-only "chapter1.rpa", you can run something like:
Code:
$ cd game/chapter1
$ arpy -o ../chapter1.rpa -g '.+\.png' .
Building Distributions
For building the project and making a zip you can ship, look no further than
You must be registered to see the links
.Renkit provides a way to download and use various versions of Ren'py, build your project, and notarize that project for use on MacOS - which is pretty awesome.
We're only interested in `renconstruct` right now, though.
The command to run should look like this:
Code:
$ renconstruct build -i=path-to-project -o=path-to-output/ -c=renconstruct.toml
Mine looks like this:
Code:
[build]
pc = true
mac = true
steam = false
[options]
clear_output_dir = true
[renutil]
version = "8.0.0"
Tying These Together
Again, as mentioned, I develop on *nix and have CI/CD set up that runs this stuff for me every time I push to my repository. How my CI/CD does this is by running commands I've specified in a configuration file - in this case, we'll look at Make.
A simple one could look like:
Code:
# Makefile example
lint:
/usr/share/renpy/renpy.sh path-to-game/ lint
recompile:
/usr/share/renpy/renpy.sh --save-dir /tmp/ignore --compile path-to-game/ compile
build-debug:
@mkdir -p build/game
@cd game/chapter1 && \
arpy -o ../build/game/chapter1.rpa -g '.+\.png' .
distribute:
@renconstruct build -i=build/game -o=build/distrib -v=8.0.0 -c=renconstruct.toml
Again, I want to stress that this post serves as an example. There are more pieces to the puzzle to be figured out, but if this is something that interests you, it's a decent starting point.
Wrapup
Thanks for reading, and I hope that you found something useful here. Happy to answer questions and help in any way I can.
Last edited: