Skip to content

Porting v3 Characters to v4#

To allow scenario authors to properly prepare their scenarios for all version of Student Transfer following v3.1, the following guide will describe the new character format that is being introduced with v4, as well as give some tips on how to properly convert existing characters to the new format.

TL;DR#

Since the guides I write tend to be longer than the great wall of China had it taken an entire bottle of viagra, here's a TL;DR for your convenience:

The Good:

  • Your story files will stay mostly untouched.
  • Assets added via the recommended method in the official guide will remain functional. This applies to Music, Sound Effects, Backgrounds and the miscellaneous images in the "assets" folder that nobody uses.

The Bad:

  • Assets of any kind added via hardcoded paths in your story file will break.
  • Custom characters will now be prefixed with your scenario prefix, meaning you will have to update their names in your story files.
  • Characters from the base game can not be extended anymore. If you do want to do that, please copy the entire character and make any changes you require to your local copy in your scenario. This helps keep things consistent and somewhat prevents dependency chains.

The Ugly:

  • We've moved to an entirely different file structure for characters. All custom characters will have to be ported to this new structure before your scenario will run.

It would be advisable to continue reading after this TL;DR since we'll now be explaining how you can effectively torture yourself for a few hours. So, giddy up while I grab the thumb screws!

Why a new character format?#

Convenience, mostly. After the initial bump, that is.
The move to the new format brings one big advantage with it: Modularisation. Whereas previously character information was strewn about several different files and folders it is now all neatly contained within one directory. This allows us to do many cool and interesting things (disclaimer: only cool and interesting if you are a programmer).
From our side, we now have more control over how characters are loaded and how we handle them ingame. Also, we got to add this monstrosity as an (April fool's) surprise for future coders.
From your side, adding new characters is now easier (fingers crossed) and less error-prone.

Directory structure for Yui
 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

What you can see in this "graphic" is that essentially, the flat file structure we had before has been pulled out into multiple sub-directories. Basically we have traded super-long, unreadable filenames for shorter, much easier to understand directories and simple filenames. Most of the data is now inferred by StudentTransfer from the folder structure itself and it is much more logically structured. We hope that this change makes it easier for people to understand even the more complex capabilities such as mutations, in the best case simply by looking at the file structure.

The below is all the metadata you need for Yui. Only the most perceptive of you will notice the almost uncanny resemblance to the previous format.

Character data for Yui
1
2
3
4
5
{
    "name_color": "#77569c",
    "eye_line": 0.04,
    "scale": 0.9
}

And now, for something a bit more complex. Cornelia is our most complicated character at the moment, so watch what happens when we apply the new character format:

Directory structure for Cornelia
 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

This already looks a bit more complicated but if you take a closer look, you'll notice that it is mostly the same as for Yui. This structure especially showcases how mutations work, as they are basically a priority set of images that gets chosen over the default one when a specific outfit is active.

And this is all the metadata you need for Cornelia. You can see that we have to enter a bit more information since we have a few special cases in here, e.g. sprites facing the wrong direction as well as several mutations.

Character data for Cornelia
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
    "name_color": "#fbca86",
    "voice": "child",
    "eye_line": 0.1,
    "scale": 0.9,
    "poses": {
        "b": {
            "facing": "right"
        }
    },
    "mutations": {
        "twintails": ["casual", "costume", "swimwear", "uniform", "uniform_b", "yukata", "cheer", "cheer_inverted"]
    }
}

There is one important piece of information you should keep in mind: The new format does not add or remove any images from custom characters, it only rearranges them. The only thing that has changed with the new v4 format is the layout of the files on disk. Any existing character that works in StudentTransfer v3.1 will work in v4 just by rearranging the existing files.

If you want to take a look at the new structure yourself, you can download the two example characters here: Yui and Cornelia.

How do I port an existing character to the new format?#

Well, let me start at the top.
In the beginning, there was light.
This was then quickly followed by despair as scenario authors realized they'd have to move and rename thousands of files manually 'til the blood ran dry of their battered hands and their tears of agony had filled the sea of sorrows to the brink. But they feared not, for the ST dev-team stood steadfast against the dying of the light, bringing them a tool to automatically convert all of their custom characters for them!

Introducing: "Harry Porter and the Shimmer of Hope"

This little utility script, dubbed "Harry Porter" because we all appreciate a good pun, will, once pointed at a character directory of v3-style characters, automatically port all of them to the new format, without you having to lift a finger. If you have the character.rpy file handy, it'll even port most of the metadata! It'll convert individual characters as well as entire directories of characters so it really is a one-stop-shop solution.

Now, the caveats:
This tool is a command-line script that requires Python, so unless you have Python installed and correctly set up, you won't be able to use this script. If you don't want to go through the whole shebang of installing Python on Windows, you can simply hit me up via PM here or on Discord and I'll convert your characters for you, free of charge no less! Since this is a one-time occurence, this shouldn't be too much of a problem, hopefully.

For those brave few souls that actually want to run the script themselves, you can find installation and usage instructions in the repository of the script.

There are only two things you as the scenario author will have to do once Harry Porter has finished running:
If you have characters with poses that are, by default, facing to the right (meaning their body is turned to the right-hand side of the image), you will have to let the game know about this deviation from the norm.
Either you flip your character images or, the simpler solution, you go into the "character.json" file for the affected character and add the following snippet:

1
2
3
4
5
6
7
8
"poses": {
    "a": {
        "facing": "right"
    },
    "b": {
        "facing": "right"
    }
},

You only have to add poses that are facing the right-hand side of the image. Simply add the affected poses with the template above and you'll be good to go.

The other thing you have to do might be slightly more tedious, depending on how good you've been with managing character images so far. Since image sizes are now inferred from the actual image files themselves (instead of you having to manually enter them), we do not support characters with legs anymore. Well, we still do, but they will show up with their legs intact and reach out of the top of the screen because of that. As such, you will have to go through and pull a Katawa Shoujo and remove the legs from all characters that have them.

If you really, really can not be assed to do that (even though it is the preferred option and will save on file size as well), you are still able to specify crop values like you could in the old format, like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
"poses": {
    "a": {
        "facing": "right",
        "image_width": 123,
        "image_height": 456,
        "center_width": 789,
        "center_height": 1011,
    },
    "b": {
        "facing": "right"
    }
},

All of these are optional, so only supply the ones you actually need, and only if you really need them.