Getting your game translated into as many languages as possible will surely help with gaining a wider audience. Luckily, Ren’Py makes translating games fairly easy.
Load up the Ren’Py launcher and select “Generate Translations”. You’ll be presented with a screen where you can enter the name of the language and select a few options. Make sure only “Generate empty strings for translations” is selected and hit the “Generate Translations” button above the option.
Ren’Py will now scan your game and generate the necessary translation files, it’s able to compile your entire script (the process will fail if your game contains any programming errors). The generated translation files will be available at the following path Your Game Name/game/tl/*language_name*. The files are just regular .rpy files with the following structure:
# game/script.rpy:19
translate klingon start_915cb944:
# "It's only when I hear the sounds of shuffling feet and supplies being put away that I realize that the lecture's over."
""
Ren’Py also uses another syntax, mostly for interface elements, such as button labels or menu items:
translate klingon strings:
# screens.rpy:251
old "Back"
new ""
You can now start translating your game by providing the translated string inside the double quotes or package everything up and send the files to your translator.
The Question in Klingon.
Every time you change something in your script you’ll need to repeat the process of generating new translation files. So click “Generate Translations”, enter the name of the translation you want to update, and hit “Generate Translations” again. Ren’Py is smart enough to keep existing translations already present in the /game/tl folder and append the new untranslated strings to the bottom of each file.
After the translation is ready, the only thing left is to wire up the ability to switch languages in the game’s preferences. The first button activates the None language, which is English by default, while the second switches to the language with the name you provided earlier.
Please beware that unfinished translation might make parts of your application unavailable, as Ren’Py doesn’t revert back to the default language when a translation is unavailable. If you need to switch back to the default language open up the developer console (Shift+O) and type: renpy.change_language(None) Your game should be in English again, or in the language, you set as default.
Some developers might expect Ren’Py to support a common standard like gettext Portable Object files (PO). This isn’t supported out of the box by the framework, but Beuc (the developer who brought us Ren’Py Web) provides a translation toolkit that makes this possible.
The game’s script has been written, renders have been painstakingly crafted and you’ve lovingly plonked everything inside your favorite development framework. Just hit publish, right? Wrong.
WebP savings compared to the original PNG
Lots of developers throw the images they just rendered in DAZ3D into their game directory without considering whether that’s the best cause of action. DAZ3D for example, outputs uncompressed PNG images by default which are lossless, which is nice, but also take up a lot of disk space. Yes, your artwork deserves to be seen, but those pretty pictures don’t need to take up over 4MB per image. Compression and finding the right balance between quality and size are key in this case.
Converting the lossless images to lossy JPEGs is a good start and will shave off quite a few megabytes, but it will only work on images that don’t require transparency. However, there’s a better image format that’s supported by Ren’Py and it offers superior compression. WebP, developed by Google, offers the same advantages as PNG (mainly alpha-transparency), but due to its compression the resulting file-sizes are much smaller.
To create WebP versions of your existing images you have a couple of options. Google offers a command line application called cwebp and a Photoshop plugin. The popular open-source application GIMP has supported WebP since its 2.10 release.
You’ll probably want to convert your images in bulk and in that case a batch converter like XnConvert (freeware) is invaluable. The process is quite simple:
XnConvert’s interface
First, whatever you do, make sure you keep your originals, the compressed versions are *not* a replacement!
Install and open XnConvert.
Drag the files you want to convert (or add them using “Add files”).
In the “Output” tab select “WebP” from the “Format” list.
Click “Settings” underneath the “Format” list.
Drag the quality slider to a value between 95 and 100, this will ensure a good compression versus image quality ratio.
Hit “Convert” in the lower-hand corner of the application window.
Replace the converted WebP images with the old ones in your game directory.
Achievements are a staple of modern gaming and an expected feature when you publish a game on Steam. Achievements are a way to encourage players to keep on playing or even replay your game multiple times. As such, Valve marks achievements as one of the features that will boost the sales of a title in their store. Luckily, Ren’Py supports achievements and adding them to your game is relatively simple.
Screenshot
First you should determine which goals you’d like a player to achieve. A mixture of easily obtained achievements and ones that are harder to get will satisfy most of your player base. As your game likely has a branching narrative with multiple choices along the way, you could for example reward a player for playing a specific branch. In my game, Sisterly Lust, people get rewarded for romancing each of the sisters, for example. Romancing a girl is an easy achievement in Sisterly Lust‘s case, but there are also ones that are harder to obtain, such as “Like a virgin” (don’t pursue any romances during a play-through) and “Two Soccer Teams” (every girl in the game gets pregnant). Make a list of achievement names, descriptions and artwork (256×256 pixel images, active and inactive versions) you want to use. It’s very important the names and artwork don’t contain any adult content, because achievements may appear anywhere on Steam.
This article deals with relatively simple achievements. Progress achievements (fuck a girl 100 times, for example) are also supported by Steam and Ren’Py through achievement.progress(), but they function a little erratically based on my experience implementing them in Sisterly Lust.
First, register all of the achievements in Steamworks (App Admin > Your Game > Stats & Achievements):
The achievements in Steamworks
API Name Progress Stat is the name you’ll use in Ren’Py to call the achievement (the “Two Soccer Teams” achievement in my game has an API name of “TWOSOCCERTEAMS”, for example).
Display Name is the name that appears on the achievement notification and on your profile.
Description is a short text about what the player has achieved.
Set By should be left as is (set to Client).
Hidden? determines whether the achievement name and description are visible in the achievement overview. Set this to “Yes” this if you don’t want that information to spoil important details of your storyline.
Achieved Icon is the version of your achievement icon when it has been obtained by the player.
Unachieved Icon is the default state of the icon, when a players hasn’t obtained the achievement.
Once you’re done with adding achievements, be sure to note all the API names you’ve entered and publish the changes. Switch back to your game, because it’s time to add the Ren’Py code that will trigger the achievements via the Steam API.
Ren’Py has several helper functions for dealing with Steam achievements. The documentation seems to indicate that just calling achievement.grant() would be enough, but for Sisterly Lust I stayed on the safe side and used the code snippet mentioned in this forum thread. So for granting the “Two Soccer Teams” achievement with the API name “TWOSOCCERTEAMS” you add the following code at the appropriate place in your Ren’Py script:
if not achievement.has("TWOSOCCERTEAMS"):
$ achievement.grant("TWOSOCCERTEAMS")
init:
$ achievement.register("TWOSOCCERTEAMS")
$ achievement.sync()
$ achievement.sync()
Repeat the process for all of the achievements and you’re nearly there.
Lastly, Ren’Py needs your Steam App ID, that the number that appears after your game’s name in Steamworks. Make a note of the number and add the following to your Ren’Py script (somewhere at the beginning of options.rpy seems like a good place):
define config.steam_appid = 1234567
Obviously 1234567 should be your App ID. Now you can test your Steam build and see if the achievements are correctly triggered.
Of course all of the above only applies to Steam. Players who download the game from another marketplace like itch.io or just from your own website will never see the achievements appear anywhere. If you want to implement achievements for all platforms, you’d have to look into rolling your own system and make it work alongside the Steam achievements you’ve set up. This article and this forum thread give some interesting pointers regarding the implementation of your own achievement system.
As with everything related to Steam, preparing copy and artwork for the feature can be quite a lot of work on your own, but a set of well-thought-out and well-placed achievements is one of the reasons a lot of players will keep coming back to your game.
One of the most daunting things about learning a new framework is knowing where to put everything so that you won’t get completely overwhelmed by the chaos of your own creation in the near future. Reading up on best practices or even cracking open an existing project by another developer and looking at the code will probably provide you some good insights into how things should be done. After over three years developing games in Ren’Py I thought I’d share some of the things I found out that might be helpful to those starting out with the framework.
A blank Ren’Py project gives you a couple of files and directories out of the box. You could just start writing your magnum opus in script.rpy and plonk all those dirty pictures in the images directory and Ren’Py would package a game for you when asked. Starting out like that isn’t much of a problem when writing a short story or creating a demo, but for larger projects some further organization is advisable.
Directory Structure
Folder structure of one of my games.
Ren’Py discovers file references anywhere in the game folder. So if you create an elaborate nested directory structure inside the image folder, you can still reference it by just using the image name in a scene statement in one of your scripts. Imagine having a file in a directory structure like this (which I wouldn’t necessarily advise):
You don’t have to provide the full path when calling roommate_fucking_doggy.jpg, this would be enough in a Ren’Py script:
scene roommate_fucking_doggy with dissolve
When you start your game, Ren’Py will automatically drill down into those five directories, find roommate_fucking_doggy.jpg and displays the image to the player when they encounter that particular scene statement. The fact that Ren’Py is smart enough to find media automatically provides you with a lot of freedom to structure your assets in a way that still makes it easy to find things at version 0.01, but also when you complete your story at version 1.0.
File Structure
Apart from making a list of file references, Ren’Py also automatically compiles any .rpy files anywhere in the game folder when launching a project. So apart from the standard gui.rpy, options.rpy, screens.rpy and script.rpy, any .rpy file in any nested folder will be considered for inclusion by Ren’Py. So instead of cramming your entire life’s work into script.rpy, you could divide your scripts into episodes or even modularize them by scene, location or whatever makes sense.
In this instance, character definitions are moved to a separate file, as is the content per episode. script.rpy would only contain the start label required by Ren’Py and jump immediately to the first episode label contained in episode001.rpy.
Adding Variables
Due to the fact that most adult games are funded through subscription platforms like Patreon and SubscribeStar, players expect to play incremental releases. One of the trickier things of releasing incrementally is ensuring save games remain compatible between releases. Of course you shouldn’t worry too much about compatibility when you’ve reworked half of your novel in between releases, you’re delivering a test build, an incremental alpha release, after all. But minor issues have a tendency to throw Ren’Py in a fit, the most common problem being undefined or missing variables.
The common way to define a variable in Ren’Py is like this: $ roommate_fucked = True This line sets up the roommate_fucked variable which can later be used in conditionals. You can use this anywhere, but if you litter your script with variable declarations, it will be hard to keep track of them. It might seem easy at v0.1, but you’ll be sorry when you need to hunt for a variable you’ve declared somewhere eight versions back.
A better way would be to declare all of your variables at the top of the file where they’ll be used:
label episode2:
$ roommate_fucked = False
$ roommate_stroked = False
$ roommate_diddled = False
$ roommate_ignored = False
"Look, it's my roommate, she's so hot."
menu:
"Fuck roommate":
$ roommate_fucked = True
mc "Hey, wanna fuck?"
roommate "Sure thing."
# Lots of fucking
"Stroke roommate":
$ roommate_stroked = True
roommate "Stop stroking my hair, you creep!"
# Fistfight ending in hospitalization
"Diddle roommate":
$ roommate_diddled = True
roommate "I love it when you play with my nipples like that in a platonic way."
# Late-night discussion on the merits of Dostoevsky's The Brothers Karamazov
"Ignore roommate":
$ roommate_ignored = True
"Nah."
# Lonely masturbation
Declaring variables like above has one problem though, it breaks backwards compatibility with saves when you introduce new variables in old code. Consider the scenario where a user has saved the game at the end of v0.1. Ren’Py saves the game state and all variables declared at that point. For v0.2 you decide to introduce a couple of additional variables to the code you’ve written previously, to better track certain choices in the game. You reference those newly defined variables in the new story content in v0.2 and that’s where the problems begin. Players who load a v0.1 save will hit undefined variable errors at that point, which can be ignored, but lead to a rather disjointed play through.
Luckily, Ren’Py has a way of declaring variables in a way that doesn’t break saved games. Enter the default statement. Prepending default to a variable declaration will make sure Ren’Py loads that variable before the game starts and populates it with the value of your choice, thus ensuring saved games will have that variable defined as well. The example from earlier will look like this now:
label episode2:
default roommate_fucked = False
default roommate_stroked = False
default roommate_diddled = False
default roommate_ignored = False
"Look, it's my roommate, she's so hot."
menu:
"Fuck roommate":
$ roommate_fucked = True
mc "Hey, wanna fuck?"
roommate "Sure thing."
# Lots of fucking
"Stroke roommate":
$ roommate_stroked = True
roommate "Stop stroking my hair, you creep!"
# Fistfight ending in hospitalization
"Diddle roommate":
$ roommate_diddled = True
roommate "I love it when you play with my nipples like that in a platonic way."
# Late-night discussion on the merits of Dostoevsky's The Brothers Karamazov
"Ignore roommate":
$ roommate_ignored = True
"Nah."
# Lonely masturbation
Handling choices
Choices are one of the things that define a visual novel as a genre. Ren’Py offers the menu structure outlined above in the code example to deal with player choices. Based on the player response one of the four variables will be set to True. Of course, those choices could easily increment the value of a character attribute (like lust, corruption or sluttiness).
label episode2:
default roommate_corruption = 0
roommate "What's that thing?"
mc "My cock."
roommate "It's so big and beautiful"
menu:
"Fuck roommate":
$ roommate_corruption += 1
mc "I'm going to fuck you with it."
roommate "Okay."
# Lots dick utilization
"Decline roommate":
mc "Sorry, I have a headache."
roommate "Okay."
# You play several rounds of Monopoly together
if roommate_corruption > 0:
roommate "I'm soooo addicted to my roommate's cock, I just love it."
else:
roommate "I feel so chaste, maybe I should become a nun."
Choice menu in The Question.
Beware though that implementing a point-based system is going to be complicated to keep track of and is a bit of a balancing act. You’ll probably want to keep a spreadsheet with the maximum values of a certain statistic at certain points in the game in order for your conditionals to make sense and not lock players out of certain scenes or story branches entirely. A simpler system based on Boolean variables might make more sense, unless you relish the abstractness of numbers.
These are some of the pointers I hope are of help to beginning developers wanting to use Ren’Py as their new development framework. Having some basic knowledge of programming and Python is a plus, although Ren’Py is pretty easy to get into.
Ever since Valve has allowed erotic content in their immensely popular storefront more and more titles have been cropping each month. If your project is nearing completion or is completed, you should seriously consider publishing your game on Steam. There’s a huge audience, largely separated from the crowd that frequents sites like Patreon or itch.io, craving new lewd content.
Preparing your content
The application to get your project on Steam costs $100 per game, this includes a (often manual) review of your game and access to the Steamworks toolset in order to market and deliver your game. The entrance fee will be reimbursed as soon as you hit $1000 in sales. Before beginning the process you should make sure you won’t fail the review process outright. Some pointers:
Remove content that might be considered illegal Steam is very lenient on what they allow to be sold in their store (incest is allowed, for example), but there are limits. Games should not include depictions of real humans engaging in sexual acts. Imagery containing characters looking underage will also result in a rejection from Valve. Explanations like “But my ten-year-old-looking vampire is actually ten thousand years old!” will probably not sway judgment in your favor. Lastly, school settings and any characters dressed in schoolgirl uniforms are problematic.
Remove any references to other platforms If you funded development of your project through Patreon or SubscribeStar, make sure you remove any links to those platforms. Steam doesn’t allow links to other marketplaces or funding platforms.
Get ready to do a lot of work As an indie dev you probably do a lot, if not all, work yourself. The process of getting a game is quite laborious, you’ll be asked to submit a lot of paperwork, set up store your store page, create a video trailer for your game and submit a library of artwork. Other than that, there are optional (but strongly recommended) features to consider, like achievements and trading cards.
Building a Steam release in Ren’Py
Once you’ve made sure your game is eligible for submission you can proceed to build a release in Ren’Py. Before the release of Ren’Py 7.4 you needed to request the Steam library files directly from the framework’s developer renpytom and manually install them, because of copyright issues. The latest release of Ren’Py can download and install the Steam library for you:
Choose “Preferences” from the Ren’Py launcher
Select “Install libraries” from the “Actions” section
Choose “Install Steam Support”
Wait for Ren’Py to restart
Theoretically you could now build three separate versions (Windows, Linux, Mac), but it’s easier to use the “Windows, Mac, Linux for Markets” option, because it creates a hybrid build.
Folder structure of the build.
Choose “Build Distributions” from the “Actions” section of the Ren’Py launcher
Select “Windows, Mac, Linux for Markets” from the “Build Packages” list
Click on “Build”
Ren’Py will create a zipped file for you containing all the necessary files. You should unzip the file, because you’ll be uploading the individual files to Steam later on. Once unzipped you should have a directory containing three folders (game, lib and renpy) and a couple of files (among themYourGameName.app, YourGameName.exe and YourGameName.sh).
Become a Steamworks partner
The Steamworks front page.
This guide won’t the entirety of the publishing procedure, because that’s well-documented in the Steamworks documentation. Instead I’ll focus on a couple of major steps in the process.
In order to get access to Steamworks you need to file the necessary paperwork (personal information, bank details). Once Valve has verified all of this, you will get access to the Steamworks dashboard. The interface may seem a little daunting at first and working with Steamworks is a peculiar experience, but it’s powerful and the only way to get your game on one of the world’s biggest gaming platforms.
Before you can use all of the features you should bite the bullet and click on “Pay Product Submission Fee”. After completing the payment process your first game will appear on the dashboard. the payment process your first game will appear on the dashboard. By clicking on it you’ll see a long list of options accompanied by a sidebar with a checklist keeping track of how far you are in the whole submission process.
Steamworks makes a distinction between App and Store admin. The former is where you’ll set up the technical details of your game, while the latter deals with the promotional (user-facing) side of your game.
Submitting a game build
Detail of the Steamworks App Admin dashboard.
By clicking on “Edit Steamworks Settings” you’ll get taken to your game’s technical configuration dashboard (also called App Admin). From here you can set the game’s name, supported platforms and add builds, achievements. The first three tabs (“Application”, “SteamPipe”, “Installation”) of this dashboard are important at this point, we’ll dig into adding achievements in a later entry of this article series.
The “Application” tab has a submenu, but the only relevant item in that list is likely just “General”. You can fill in the name of your game and supported operating systems here. One thing to note here is the mention of “Notarized App Bundles” for macOS. As an extra security feature, Apple has been requiring applications to be notarized on their operating system. This means that you need to apply for a membership of the Apple Developer Program (costing $100 per year) and create the necessary notarization certificates. Ren’Py can theoretically create notarized app bundles, but the process isn’t very well-documented. While non-notarized applications do run, it requires some intervention on the user’s part, allowing software to run from any source. Because of this, it’s probably easier to forgo supporting macOS on Steam.
We’ll deal with the “SteamPipe” section once you’re ready to upload your game.
Both “General Installation” and “Client Images” are of interest. You set up the install folder and launch options in “General Installation”. Because you’ve created a hybrid game build in Ren’Py, you can just create the launch options for all the operating systems you want to support. The executable name should be set to either YourGameName.exe (Windows). YourGameName.app (macOS) or YourGameName.sh (Linux). The “Client Images” section is where you should upload the application icons of your game.
Once you’ve set everything up, you should select “Publish” at the far end of the dashboard button row. Click “Prepare for publishing” and then, if there are no errors, “Publish to Steam”.
The folder structure of the Steam SDK.
Now you’re ready to upload a build using SteamPipe. There is an option to upload zipped files directly using a web form in Steamworks, but the file size is limited to 2GB and the process is far less robust than using SteamPipe. Also, SteamPipe is smart about uploads, so when you’re uploading an update version of your game it will only upload the changes compared to the original (so-called delta patches).
First, download and install the Steamworks SDK. Setting up the SDK differs on each operating system (there’s a GUI available for Windows, for example) and Steam advises to create a separate user to upload game builds, so refer to the documentation for more details.
Once you’re finished you should have a directory SDK directory containing several subdirectories, on of which should be called tools. The tools directory in turn contains a ContentBuilder directory (and several others) holding six subdirectories (builder, builder_linux, builder_osx, content, output and scripts).
Place the all of the files from the build directory generated by Ren’Py inside tools/ContentBuilder/content.
Find the application and depot ID in Steamworks. The application ID is the number next to the game’s name in the App Admin. The depot ID can be found by hovering over “SteamPipe” and clicking “Depots”. If there are no depots, create and configure one, otherwise note the ID in front of the depot name.
Using your favorite text editor, create two files in tools/ContentBuilder/scripts called app_build_YOUR_APPLICATION_ID.vdf and depot_build_YOUR_DEPOT_ID.vdf. The contents of the files should look like the following:
depot_build_YOUR_DEPOT_ID.vdf
"DepotBuildConfig"
{
// Set your assigned depot ID here
"DepotID" "YOUR_DEPOT_ID"
// Set a root for all content.
// All relative paths specified below (LocalPath in FileMapping entries, and FileExclusion paths)
// will be resolved relative to this root.
// If you don't define ContentRoot, then it will be assumed to be
// the location of this script file, which probably isn't what you want
"ContentRoot" ""
// include all files recursivley
"FileMapping"
{
// This can be a full path, or a path relative to ContentRoot
"LocalPath" "*"
// This is a path relative to the install folder of your game
"DepotPath" "."
// If LocalPath contains wildcards, setting this means that all
// matching files within subdirectories of LocalPath will also
// be included.
"recursive" "1"
}
// but exclude all symbol files
// This can be a full path, or a path relative to ContentRoot
"FileExclusion" "*.pdb"
}
app_build_YOUR_APPLICATION_ID.vdf
"appbuild"
{
"appid" "YOUR_APPLICATION_ID"
"desc" "Reinstate patch and extra scenes" // description for this build
"buildoutput" "..\output\" // build output folder for .log, .csm & .csd files, relative to location of this file
"contentroot" "..\content\" // root content folder, relative to location of this file
"setlive" "" // branch to set live after successful build, non if empty
"preview" "0" // to enable preview builds
"local" "" // set to flie path of local content server
"depots"
{
"YOUR_DEPOT_ID" "depot_build_YOUR_DEPOT_ID.vdf"
}
}
You’re now ready to upload the build by running the command to upload the build. On Windows:
If the command finishes successfully your new build should now be uploaded and available in Steamworks under “Builds” in the “SteamPipe” tab. This doesn’t mean however that the build can be downloaded and played via the Steam Game Client. In order to do that you need to select the build you’ve just uploaded and attach it to a branch. You can create your own additional branches, but the default branch is the one that will allow you to push a new build to the game client. Select the default branch and preview the change.
Move over to the “Publish” tab again and select “Prepare for publishing”. If all goes well you should hit “Publish to Steam”. The game is now live and downloadable. Of course, if your game hasn’t been approved yet, the downloads are only available to you.
Setting up your store page
The Steam store page for one of my games.
Having set up your first build, you can now move onto creating your store page. Go back to the Steamworks dashboard and select “Edit Store Page”, this will take you to the Store Admin section. From here it’s just a question of filling in all the relevant information on all of the tabs.
In the “Basic Info” section, be sure to fill out all of the information truthfully. Steam requires you to take a “Mature Content Survey” where you list the nature of the sexual content in the game and where they ask you how to reach any scenes of a sexual nature quickly for review. This is also the tab where you can indicate support for any additional languages. As an aside, having your game translated into German, French, Spanish, Portuguese and Russian widens your potential audience.
The “Ratings” tab has one noteworthy section regarding sales in Brazil. If you want to sell your game in that country you’ll need to take questionnaire and answer quite a lot of questions. Other than that, if you don’t have an rating for your game by an official board, don’t fill in any other ratings.
The “Graphical Assets” and “Trailers” section are self-explanatory. Make sure that any image you upload is safe for work, so nudity or characters in compromising poses. However, sexual content is allowed in the trailer and screenshots you upload, because these can only be viewed on the store page itself after dealing with an age gate.
After you’ve entered all of the information and uploaded all of the assets you’re ready to publish. Once again, the changes will only become visible to you if your game hasn’t been approved yet.
By now the todo list on the Steamworks dashboard should look a lot less incomplete.
Coming up with a release date
Setting your release date in Steamworks.
Plan your release date carefully. You need enough time to setup your store, implement any achievements, create all the imagery and produce a trailer. Also factor in dealing with the application review and any changes that might result from that. Steam Support usually replies within a couple of business days, but the review process might take longer. Especially for adult games they do a more thorough check in addition to any technical issues or discrepancies between your game and what’s listed on the store page. Having a release date comfortably in the future also gives you time to market your game once it has been approved and to get on player’s wish lists.
Getting your game onto Steam is quite a journey, but believe me when I say it’s worth it.
Ren’Py already allows us to build games for Windows, Linux, macOS and Android. With the release of Ren’Py 7.3, the framework has gained the option to create HTML5 builds. Apart from being a regular contributor to the main Ren’Py project, beuc has been porting the framework to modern web browsers. Ren’Py Web is still in beta and has some limitations I’ll get into later, but is quite feature-rich.
Why build a web edition?
The Ren’Py web edition build screen.
As mentioned earlier, Ren’Py allows you to publish your game on many platforms already. Unfortunately, iOS (Apple’s operating system for mobile devices) is out of reach for us erotic games developers. Because the only feasible way to publish games on iOS is via the App Store and Apple doesn’t tolerate any pornography on it, developers are left with little other options. Luckily Ren’Py Web runs just fine in Safari for iOS…
Publishing a web edition on your own server, or a storefront like itch.io, Newgrounds or Game Jolt is a great way to expand your audience. Also, you can cater to players who are unable to play your game on the platforms supported by Ren’Py.
Preparing your content
There are a couple of things to keep in mind when building a web edition:
Don’t waste too much of the player’s bandwidth Some people are still on dial-up or dealing with metered bandwidth, so you should make sure your game’s assets are compressed thoroughly. As of Ren’Py 7.4 the web build should be smarter about downloading resources, but it still makes sense to optimize. People don’t expect a web edition to be an Ultra HD affair, so convert your images to WebP (which you should do anyway) and compress them until you have achieved a good quality to file size ratio.
Remove any video files If you have animations in your game and you’re referencing them as video files (webm, mp4, etc.), you should remove them. Currently (at Ren’Py 7.4) doesn’t offer video playback and the game will halt as soon as it encounters a video file. Support for video might be coming in the future, but in the meantime you should remove them and swap them for a static frame of the animation. Animations made using Ren’Py’s Animation and Transformation Language should run without issue.
Provide a splash image By adding an image named web-presplash.webp (can be a PNG or JPEG as well) to the top-level directory (so above the game directory) you can provide a message to web players (for example noting the limitations of the web build).
Building and uploading the web edition
The directory structure of the web edition of The Question.
Building a game should be as easy as selecting the “Web (Beta) option in the “Actions” section of the Ren’Py launcher. Ren’Py will create a directory for you containing all the files necessary to run the game in a browser. Double-clicking the index.html file in the folder won’t do much though, as the web edition requires a web server.
Upload to your own web server You can just upload the files to a directory on your web server and point your browser to the address. If you run an Apache server you should add the contents of htaccess.txt to an .htaccess file in the directory where you uploaded the files.
Upload to itch.io or Newgrounds Uploading your game to any of the three websites above is a matter of zipping up all of the contents in the web build directory Ren’Py created and upload that ZIP file to the websites mentioned above.
itch.io allows you to host web games by setting the “Kind of project” from “Downloadable” to “HTML” when creating a new project. Please note that HTML5 games cannot be sold on itch.io, you can only ask for donations.
On Newgrounds, be sure to check the “Touchscreen friendly” option (“HTML5 Archive (zip)” > “Edit Properties”), otherwise your game will be marked as incompatible for touch devices.
With the release of Ren’Py 7.3, creating a web edition of your game has become a piece of cake and a great addition to Ren’Py’s platform support.
Manage Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.