How to make your Ren'Py game fully compatible with Sandbox Adventure?

Sandbox Adventure can import automatically Ren'Py games but there are some limitations. So here is a quick guide about how to make a game fully compatible.

Most tips can actually be followed on every Ren'Py project, no matter if you want to make it compatible to Sandbox Adventure or not. It is just one way of coding correctly a Ren'Py game. Conversion only tips are therefore tagged.

If your game is already finished or to far advanced to apply some of those tips, don't worry, it can still be compatible with Sandbox Adventure (most games are). The conversion will just be harder!

Automatic image importation

Since version 6.10, it is possible to automaticaly import all the images with a new configuration variable.

Instead of doing defining manually every images:

image eileen sad = "images/eileen/sad.png"
image bg forest = "images/bg/forest.jpg"
[...]

You could simply add the following code in the options.rpy file:

# activate automatic image importation
config.automatic_images = [ ' ', '_', '-', '/' ]
# allow to gather all images in the /game/images folder without having all the name starting with "images"
config.automatic_images_strip = [ 'images' ]

With this code, Ren'Py will automatically create a variable for each image file included in the game folder. It will use the directory structure to name the variables:

  • /images/eileen/sad.png => eileen sad
  • /images/bg/forest.jpg => bg forest
  • /images/bg/forest-night.jpg => bg forest night
  • /images/cg/lucy/kiss.jpg => cg lucy kiss

It is not compulsary to gather all images in the /images folder, but it is always good to organize your game folder, see tip below.

Organizing the game folder

It is usually not a good idea to save every assets directely in the root folder. The more assets you add, the messier it gets. Organizing your assets in folder will let you keep everything in order while greately facilitating the file optimizing process (see in another tip below). Linked with the automatic image importation, it will make image names more consistent.

Here is an example of folder hierarchy:

  • /game/audio => audio files
  • /game/images/bg => background images
  • /game/images/cg => illustration images
  • /game/images/gui => user interface images (textbox, buttons...)
  • /game/images/eileen => Eileen's sprites images
  • /game/images/lucy=> Lucy's sprites images
  • /game/images/side/lucy=> Lucy's side images

Linking an image to a character

It is possible to link displayed images to one character so you don't have to hide and show their sprites everytime you want to change their expression.

# defining the images (useless if you activate the automatic image importation)
image eileen = "eileen/normal.png"
image eileen happy = "eileen/happy.png"
image eileen sad = "eileen/sad.png"
# defining the character
define e = Character ('Eileen', image='eileen')
[...]
# long way
show eileen
e "I am normal."
show eileen happy
e "I am happy."
show eileen sad
e "I am sad."
[...]
# short way
show eileen
e "I am normal."
e happy "I'm happy."
e sad "I am sad."

More information in Ren'Py documentation.

Screen resolution

Ren'Py default screen resolution is 800x600. As you can see here, about 97% of people have a screen resolution of 1024x768 pixels or higher. Moreover, most computers have a 16:9 widescreen display instead of 4:3. So, why keep using of format that nobody uses anymore? That's the reason why most Ren'Py project are now made in 1280x720.

init python:
    config.screen_width = 1280
    config.screen_height = 720

With the democratisation of high definition, it could even be worthwhile to chose a higher resolution like 1600x900 or even 1920x1080. But it will highly increase the size of the game in Mo.

Image can be easily downsized, but will appeared pixelated if enlarged. It is therefore adviced for graphist and illustrator to work on high resolution images and reduce the file dimension at exportation. By doing so, you leave open the possibility of increasing the screen resolution later.

Optimizing images

Not everybody has a fast internet connection and a lot of empty space of his/her hard drive. Along with audio files, images contribute a lot to the final size of a game. When creating a Visual Novel, any author should try to optimize images in order to reduce file size in Mo.

The procedure is not complicated and doesn't take a lot of time. You can easily divide by four the total image size in less than one hour of work. Just follow the few simple steps explained on this tutorial.

Sprite size

This tip is only useful for compatibily reason. 

Sandbox Adventure is responsive. The image sizes change according to the screen resolution and a sprite always take all the available height on screen. To preserve the height differences between the characters, every image should have the same canvas height even if the sprite is smaller.

If the project resolution is 1280x720, every sprite should be 720px high. The width does not matter. Smaller characters will have more empty space over the head and height difference will be preserved.

                        

Changing a character name

In many games, a dummy name is displayed when the main character meet a new person. It is usually something like "????", "Unknown person", "Friendly shopkeeper" or "Angry client". It is only after the proper introduction than the real name is displayed. There are two common ways to change the character name during an adventure: defining different characters or using the DynamicCharacter class.

Unfortunately, the DynamicCharacter class is not compatible in Sandbox Adventure where a character keep the same name during all the adventure. Of course, you should keep using DynamicCharacter class for characters that are named by the player, since there is no other solution in Ren'Py. I will have to make a little workaround, but it is not really complicated. But please avoid using DynamicCharacter for other purpose.

The other solution is to use several characters, one by name. Most author use the same character every time you don't know the name of someone of when you don't see the person that is talking.

# global unknown character
define u = Character('????')
# Eileen
define e = Character('Eileen', image='eileen')
# Lucy
define l = Character('Lucy', image='lucy')
# first time you meet Eileen
u "You don't know me."
e "I'm Eileen, nice to meet you."
# first time you meet Lucy
u "You don't know me either."
l "My name is Lucy."

It is -almost- working great in Ren'Py, since the dialog box show "????" in all case.

But things are different on Sandbox, since every text said by a character is displayed in a speech bubble next to his/her sprite. So the script needs to know to whose sprite it should link the text to. The name of the character only matters when the his/her sprite is not shown on screen.

Here is a way to make it work in Ren'Py and Sandbox:

# Eileen
define e = Character('Eileen', image='eileen')
define eu = Character('????', image='eileen')
# Lucy
define l = Character('Lucy', image='lucy')
define lu = Character('????', image='lucy')
# first time you meet Eileen
eu "You don't know me."
e "I'm Eileen, nice to meet you."
# first time you meet Lucy
lu "You don't know me either."
lu happy "I can smile easily."
l "My name is Lucy."

Besides making it compatible to Sandbox Adventure, it leaves you the possibility to change later the "????" by any other dummy name like "Friendly stranger" or "Annoying kid". Moreover, it links sprites to the unknown characters, allowing you to change expressions without using the show function (see tip above).

You can still use the global unknown character when the character is offscreen and no sprite is displayed.

Back to the beginning of the guide