Skip to content

Characters And Images#

Having a story is all fine and dandy, but this wouldn't be a visual novel without any actual visuals, would it? To remedy this situation, the game includes a system for displaying images of characters and backgrounds for them on the screen. Braille is not supported at the moment, except if your screen somehow possesses the ability to create protrusions on its surface, in which case possess(ed) is probably the key word to look out for in this sentence.

Ren'Py uses the show keyword to tell the game when to display a specific image. Of course for that to work you need to tell it which image to display and this is where the integrated sprite viewer comes into play. If you head over to it and select a character, it will show you a list separated into Outfits, Accessories and Expressions. Depending on the character, the Accessories section might be missing if none are available.

Outfits change what the character is wearing.
Accessories denote small things like hairbands or cameras that can be added or removed.
Expressions determine the expression on the characters face.

Just like with the names of the characters, the names of the different items in the list are the ones you can use in the script to refer to them. Using this viewer you can determine which keywords you will need to use to get a specific combination of these things to show up in your scenario.

Let's give a more concrete example. Since we've made john talk already, we should now probably show him on the screen as well. If you select him in the sprite viewer, you can pick-and-choose what you want him to look like. Let's leave him in his uniform but select the a_7 expression. Now remember those two keywords.
This is how a script with john included as an image might look like:

1
2
3
4
5
6
7
8
outfit john uniform
"At first, there was thought."
think "No there wasn't."
show john a_7 at center
john "Oh, shut up, brain!"
"The protagonist seemed a bit nervous at the unexpected breaking of the fourth wall."
show john a_0
john "And you too, narrator!"

Note that we set johns outfit in the beginning with the outfit statement. We can do this wherever we want and john will stay locked in that outfit until we use the statement again to change it.
In between the thought and speech statements a show statement has appeared. To display a character you first tell it which one to use, in this case it's john, and after that you tell it which expression the character should have (a_7). If the character is not on the screen already, you should also tell the game where to position it. This is achieved by adding an at after defining the character and telling it a position (can be left, centerleft, center, centerright or right).

In this script, an angry john would appear after the thought, simultaneously with his first speech statement. You can use the same statement again to change his expression, like we did before his next line.

If you want to add accessories to a character, you can do so with the accessory command. Just tell it the character you want to change and list the accesories you want, like this:

1
accessory sandra set bedhead, glasses

To remove all accesories, you can simply call this:

1
accessory sandra clear

Adding custom characters#

A feature we added in v3 of the game was custom characters. Well, with v4 we're doing it again, this time (hopefully) improving on the process from when it was first introduced, in an ongoing effort to make creating scenarios simpler and more streamlined.

To get started, you will have to create a new folder in your scenario package called - who would have guessed - characters. This folder will contain sub-folders for each character you want to add. For example, say you want to add the character Eliza to the game, you would create a sub-folder called eliza in the characters folder. This has already happened in the case of the example scenario, so feel free to take a look to get a better idea of what the following instructions actually result in.
The eliza folder is where the actual character images should be stored. Unfortunately, you will have to adhere to the way that we do things in the main game, which means you will have to separate the expressions of the characters from their bodies, which effectively boils down to cutting out their faces from the main sprite and saving them on their own.
For this, a convention for naming and organizing things exists so the game can recognize them.

Anatomy Of A Character Folder#

In v4, all images pertaining to a character are organized in a directory structure that represents how the game understands the concept of a character. They are split into folders for poses, outfits and faces.

A pose is a letter (or multiple) that groups the expressions for a specific pose the main sprite has. It is a stance the character is in in the main sprite that a set of expressions will fit on. For example, if a character faces the viewer, with a set of expressions that will fit on that sprite, we would group them under the same pose to indicate that they belong to that stance of the character.
If the character has a second pose e.g. in which they look to the right, the expressions from the first pose will not fit on their face. As such, we make this a different pose and group all expressions that fit this pose under that name instead.
In the case of the base game, we simply name poses with increasing lowercase letters, starting with a.

The pose grouping is followed by a second layer of folders (which you can also see in the examples below): expressions and outfits. What exactly these are will be explained in the next sections.

Info

To make this a bit easier to understand, let's take a look at a few example characters: Yui and Cornelia. The following snippets have been shortened for your convenience by removing some face files, but other than that they are actual snapshots from what any character added to the game will look like.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
yui/
├── a/
│   ├── faces/
│   │   ├── blush/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   └── face/
│   │       ├── 0.png
│   │       └── 1.png
│   └── outfits/
│       ├── casual.png
│       ├── gym.png
│       ├── nude.png
│       └── uniform.png
├── b/
│   ├── faces/
│   │   ├── blush/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   └── face/
│   │       ├── 0.png
│   │       └── 1.png
│   └── outfits/
│       ├── casual.png
│       ├── nude.png
│       ├── swimsuit.png
│       ├── swimsuit_covered.png
│       └── uniform.png
└── character.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
cornelia/
├── a/
│   ├── faces/
│   │   ├── blush/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   ├── face/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   └── mutations/
│   │       └── twintails/
│   │           ├── blush/
│   │           │   ├── 0.png
│   │           │   ├── 1.png
│   │           │   └── makeup/
│   │           │       ├── 0.png
│   │           │       └── 1.png
│   │           └── face/
│   │               ├── 0.png
│   │               ├── 1.png
│   │               └── makeup/
│   │                   ├── 0.png
│   │                   └── 1.png
│   └── outfits/
│       ├── casual.png
│       ├── costume/
│       │   ├── bottle/
│       │   │   ├── off.png
│       │   │   └── on.png
│       │   └── costume.png
│       ├── nude.png
│       ├── pajamas.png
│       ├── uniform.png
│       └── uniform_b.png
├── b/
│   ├── faces/
│   │   ├── blush/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   ├── face/
│   │   │   ├── 0.png
│   │   │   └── 1.png
│   │   └── mutations/
│   │       └── twintails/
│   │           ├── blush/
│   │           │   ├── 0.png
│   │           │   ├── 1.png
│   │           │   └── makeup/
│   │           │       ├── 0.png
│   │           │       └── 1.png
│   │           └── face/
│   │               ├── 0.png
│   │               ├── 1.png
│   │               └── makeup/
│   │                   ├── 0.png
│   │                   └── 1.png
│   └── outfits/
│       ├── casual.png
│       ├── cheer.png
│       ├── cheer_inverted.png
│       ├── costume/
│       │   ├── bottle/
│       │   │   ├── off.png
│       │   │   └── on.png
│       │   └── costume.png
│       ├── nude.png
│       ├── pajamas.png
│       ├── swimwear.png
│       ├── uniform.png
│       ├── uniform_b.png
│       └── yukata.png
└── character.json

Expressions#

Faces cut from the main sprite are called "expressions". In the character folder they inhabit the second level of grouping after the pose and are organized like this:

1
2
3
4
5
faces/
├── blush/
│   └── <number>.png
└── face/
    └── <number>.png

The <number> is simply a way to distinguish different expressions. We normally start at 0 and go from there until we either run out of expressions or numbers, whatever comes first.
Take a look at the above examples to see how this would fit into the complete structure.

You can also take a look at our git repository and explore the files to see how our character system is organized, should you need more examples.

Bodies#

The siamese twin of having a face, naturally, is having a body, a thing that most people likely can relate to. This is the main sprite that you cut the face out off, with exactly that part missing. In Student Transfer this constitutes an outfit and will appear like this in the character folder:

1
2
outfits/
└── <name>.png

<name> can be whatever you want it to be and is the name you will use to refer to this outfit in-game. In the case of Eliza, who has a uniform outfit, the file is simply named like this:

1
2
outfits/
└── uniform.png

Just like faces, outfits are part of the second layer of grouping, beneath a specific pose.

Registering your character#

Now, at this point, if you were to add your assembled character folder to your scenario and load up the game, it would already display. However, there is one more step to making a complete character: Adding Metadata.
This means data that helps the game display your character correctly, e.g. scaling information, the proper display name, the color of their name and some other things.
The game will run fine without, but your character will have a very barebones setup.

To do this, you will have to create a new file in the folder of the character you want to add metadata to, which should be named character.json.

Warning

One some operating systems, file extensions are hidden by default, so you might have trouble seeing what extension your file actually has. Please consult a guide for your specific operating system to figure out how to show these extensions if you're having problems with the game not picking up your newly created file.

Student Transfer operates on a need-to-know basis, meaning that you can add as many or as little of the expected information as you want, depending on how complex you want to get. Every single line save for the first and last in the following example is optional, so keep that in mind while going through it.

Into your newly created character.json file you can insert the below template. Please note that you will have to change these values before they will work for your character!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
    "name": "Eliza Hintre",
    "name_color": "#915f40",
    "voice": "girl",
    "eye_line": 0.195,
    "scale": 0.6,
    "poses": {
        "a": {
            "facing": "right"
        }
    }
}

Tip

This is what's called a JSON file. These files follow a simple format where the name of a property is on the left-hand side of every statement, followed by a : and the actual value of that statement. Take care to only ever edit the right-hand side of these lines as Student Transfer relies on the correct spelling of the property name to detect your data.

If you're having problems with the game not accepting your character.json file, try running it through a JSON Validator, which will show you any errors that you might have made while entering your data.

You can find the same file in the example scenario, specifically for the character eliza, should you want to take a look at it in the wild or possibly play around with it when it's already set up.

Ideally, every character you add should have one of these files in its folder. It might look intimidating at first, but don't worry, we'll go over what each line does in detail right now.

1
"name": "Eliza Hintre",

The right-hand-side of this statement defines the name that will actually be shown in-game and it can be anything you want. Please try to choose a name that's not already in use to avoid confusion when multiple scenarios are installed.

1
"name_color": "#915f40",
This sets the color of the name that will eventually show up in-game. It is a hex-color, so you can use any color-picker you want to either convert whatever color-format you have to hex or just straight-up pick a color you want and copy it in this format.

1
"voice": "girl",
This sets the tone of the "beeps" you hear when you enable "voice" in the preferences. There are several voices to choose from, each with a different tone to it, which mainly comes down to pitch in our case:

  • deep
  • male
  • john
  • kiyoshi
  • tomboy
  • woman
  • girl
  • child

1
"eye_line": 0.195,
This should be set to a value ranging from 0 to 1 and determines the offset from the top of the image to the eyes of the sprite. This is only used for the scry effect, and you will most likely be able to ignore it entirely and just leave the value at 0. However, if you notice that the scry effect is zooming to the wrong part of the sprite, you can remedy that by adjusting this value.

1
"scale": 0.6,
This is more of a convenience function. If you character appears too large or too small, you can set a value other than 1.0 to scale them up or down respectively, depending on whether you choose a larger or smaller number.

Warning

Try to get as close to a scale of 1.0 as possible. Sprites that are too small will look pixelated in the game while sprites with a much higher resolution waste disk space and will negatively affect performance.

1
"default_outfit": "uniform",
This defines the outfit that your character appears in when nothing else is specified, so it should be an outfit that actually exists. The name should be the name of an outfit you defined in the previous step.

1
2
3
4
5
"poses": {
    "<pose>": {
        "facing": "right"
    }
}
Student Transfer presumes that all your sprites are oriented such that they face to the left side of the image. Should you have added a pose that has the character look the other way (to the right), you'll have to tell the game about this deviation from the norm. This is used within the game to ensure that all characters consistently face the correct way.
For every pose you have that does not face to the left, add the inner part of the above snippet, replacing <pose> with the actual name of the pose you want the game to know about. Leave the "facing": "right" line as it is.

Once you have defined one or more of these properties your character should come to life in the game. After a restart or reload you should be able to see it appearing in the sprite viewer. If it does, you did everything correctly and you are free to go and use the character like any normal Student Transfer character in your scenario.

Warning

With v4 of Student Transfer, all your custom characters' script-names will be prefixed by your scenario prefix. This means that the character eliza will end up being named example_eliza, in the case of the example scenario. This was done to separate characters from different scenarios and thus reduce conflicts, i.e. if they happened to have the same name.

Images#

The game includes an array of background images you can use. You can find a list of these in the Background Gallery included with the game.

Showing a background will generally look like this:

1
scene bg main house day

The scene keyword is similar to the show statement, with the added bonus that it removes all previous images from the screen. If you set a scene, the screen will be blank except for the background image.
Background images are composite names, meaning they consist of multiple space-separated words, however they still form a single image name in the end. In this case, we are showing a background image (bg) related to the main character (main). Here it is his house in the day variation.

The script name of every available background is listed in the Background Gallery.

Adding custom images#

At some point you might want to add your own images to the game. This is possible, but there are some rules you have to follow for it to work correctly.
When you create a scenario, you will find two folders next to the story/ folder, namely bg/ and assets/. The bg/ folder is designated for background images. You can put your own custom ones in there in case you can't find what you need in the images provided by the game. Just make sure that your images are in the PNG format and have an aspect ratio of 16:9, preferrably with a resolution of 1280x720. You don't have to do anything else. Once you restart or reload the game, whatever valid images you placed in there will be available for you to use in-game.

Tip

It is recommended to use as many of the built-in assets as possible to save on filespace and get better performance since less custom assets have to be loaded.

The same goes for the assets/ folder, except here you don't have to watch the image size or aspect ratio. There is no difference between these two as far as functionality goes, it is merely a way of logically distinguishing between background images and other images you might need that don't fill the whole screen. You can see examples for both kinds of images in the example scenario.

The last thing you have to be aware of before you're able to use your custom images in-game is the way they're referenced in the code. The format of the image names generally follows the same rules as were explained above, however to prevent conflicts with other people's images, your image names will be prefixed by a scenario-specific string, mostly just a few characters long, which is defined in the scenario.json file of the respective package. In the case of the example scenario that would be example, so any custom background images would look like this:

1
example_bg <image name>

For asset images, you would use:

1
example_asset <image name>

Be aware that filenames are split at spaces, so the file street night.png becomes example_bg street night in the code. Also, sub-folders will be incorporated into the final image name, as can be seen with the images in the assets/ folder, where the file assets/demo_6/no_edges highlight_1.png becomes example_asset demo_6 no_edges highlight_1 in the code.