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:

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:

accessory sandra set bedhead, glasses

To remove all accesories, you can simply call this:

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.

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.yml
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.yml

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:

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:

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:

outfits/
└── uniform.png

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

Accessories#

Sometimes, a character has things aside from their expressions that you may want to be able to toggle on or off. These are normally things like watches, glasses, wrist bands, ties etc. For this reason, we call these items accessories, since that's what they typically are.

Accessories are generally bound to a specific outfit in a specific pose, because they often times contain pixels from the base outfit they came from, making it hard or impossible to reuse them for other outfits as well.

Creating an accessory for a specific outfit is support by creating a folder inside the outfits directory and putting the actual outfit image as well as a sub-folder for the accessory inside it. The name of the folder which contains the accessory images determines the name of the accessory.

Such an accessory normally looks like this:

outfits/
└── <outfit_name>/
    └── <accessory_name>/
        └── on.png
        └── off.png
    └── <outfit_name>.png

As you can see, the accessory has two states off and on. These names are fixed, so you should name your files exactly like this when creating an accessory. The off image is optional in case your outfit already contains the base off state, so in many cases you will only need to add the on variant.

Multi-State Accessories#

So much for the basic accessory system. In some cases however, you want to do more. Specifically, we support multi-state accessories which can have more than one on state. There is still a singular off state, but you can add an underscore (_) and a name for the on state to any of the other images in the accessory folder, like so:

outfits/
└── <outfit_name>/
    └── <accessory_name>/
        └── on_<state_name_1>.png
        └── on_<state_name_2>.png
        └── off.png
    └── <outfit_name>.png

In the game, this would then be referenced as the accessory name and the state name joined together with an underscore, such as <accessory_name>_<state_name_1>. For Sadie, as an example, you have the option of setting hair_ponytail or hair_twintail, both of which are states of the hair accessory.

Pose Level Accessories#

Sometimes, you happen across a rare case where you can actually reuse a single accessory image across multiple outfits of the same pose. This can happen with extra assets for glasses, for example, which can just be overlaid anywhere.

To support such cases and to prevent you from having to painstakingly copy the same accessory to all of the outfits inside the same pose, we support pose-level accessories. These apply to all outfits in the same pose and are sourced from a single accessory folder, centralizing the assets needed for this accessory and making management of your files much easier.

To create a pose-level accessory, create a folder inside the outfits directory that begins with acc_ (for accessory), followed by the actual accessory name, like this:

outfits/
└── acc_<accessory_name>/
    └── on.png
    └── off.png

For Sadie, as an example, there exists an acc_hair accessory on the pose level which applies to all of her outfits in the given pose. Other than the location and name of the folder, the accessory behaves exactly the same as regular outfit-level accessories.

One feature that pose-level accessories have but outfit-level ones don't is the ability to selectively turn them off (or even just turn off a particular state) per outfit.

This is done via the character metadata in character.yml and looks like this:

poses:
  a:
    facing: left
    excludes:
      <accessory_name>:
        - <outfit_name_1>
        - <outfit_name_2>

For Sadie, for example, you could disable her hair accessory entirely for the casual outfit and only her ponytail accessory state for the uniform outfit like so:

poses:
  a:
    facing: left
    excludes:
      hair:
        - casual
      hair_ponytail:
        - uniform

This is useful for accessories which apply to most outfits in a pose, but not all. In such cases you can turn the pose-level accessory off entirely if it doesn't fit for a particular outfit.

Instead of turning accessories off entirely, you also have the option of adding an accessory with the same name on the outfit level, which will then take precedence over the pose-level one.

For Sadie, as an example, you could override her pose-level hair accessory for the uniform outfit specifically like this:

outfits/
└── acc_hair/
    └── on.png
    └── off.png
└── uniform/
    └── hair/
        └── on.png
        └── off.png
    └── uniform.png

This would override this accessory in just this pose and it would "just work" inside the game, automatically switching between the pose-level and outfit-level accessory depending on the outfit of the character.

Layering Accessories#

Yes I know this is getting long, but wait, there's more! Specifically, we have one more feature which could be useful for advanced users, which is setting the layer of the accessory.

Sometimes you have something like a different hairstyle that you want to use as an accessory. You could go ahead and painstakingly cut out all the parts where hair overlaps with the character etc, but that would make it very painful to reuse across various outfits which have slightly different outlines.

Instead, wouldn't it be nice if you could just layer the accessory behind the character instead of in front of it? That way, you could create a single hair accessory and just layer it behind the outfit and expressions, which would remove the need to mess around with cutting things out exactly.

Well, now you can! Any accessory -pose-level or outfit-level- can have a symbol and a number appended to it which will determine whether it shows up behind or in front of the outfit and expressions, and by how much. Incidentally, this also allows you to layer multiple accessories over each other, if you so desire.

By default, accessories are overlaid on top of everything else since that is the most common thing you may need to do when adding one. If you want to set the layer, you may add -<number> to set a layer behind the sprite (with bigger numbers being further back) or +<number> to set a layer in front of the sprite (with bigger numbers being further in front).

As an example, Sadie's hair is displayed behind her outfit and expressions by setting acc_hair-1.

You may select numbers between 0 and 9 (single-digit), so you can go up to 9 layers back and 9 layers in front, with 0 being the default layered right on top of the outfit and expression images.

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.yml.

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.yml file you can insert the below template. Please note that you will have to change these values before they will work for your character!

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 YAML 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.yml file, try running it through a YAML 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.

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.

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.

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

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.

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.

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.

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:

scene bg house_davis exterior 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.yml 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:

example_bg <image name>

For asset images, you would use:

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.


Last update: April 16, 2022