Over the years I’ve created a number of converter programs for porting visual novels to VNDS format. While porting will never be an exact science, I’ve gradually hammered out an approach that works best for me.
1. Find an appropriate title to port
Not everything works well for porting. In particular, you’d need to take the limitations of VNDS into account — it doesn’t support any form of animation/movement and mini games are basically impossible to port due to the extremely limited scripting support. Some VNs may also be easier to port than others, older and more linear titles usually have a less complex script and are therefore easier to port. Which engine the VN is built in also matters, common and especially open source engines will have more documentation and tools available than obscure or proprietary engines.
Especially important is whether the scripts are stored in plain text or in bytecode. Rarely do tools exist to convert a bytecode script back to its textual form and text scripts are much easier to figure out and especially parse. The difference in understandability between
0x1F should be obvious. Always try to look at the scripts first before deciding what to port. You may need to extract them from an archive file first (see next paragraph).
2. Unpacking the resources
For most engines, resources (scripts, images, audio) are stored in a number of archive files. These take up the bulk of the VNs total size and often have names ending in
.arc or something similar. These are usually in a simple to figure out, but engine-specific file format. What’s great is you very often don’t even have to figure out the file format because someone has already done it for you. For most mainstream VNs, CRASS is able to extract (and sometimes decode) the archive files. In the rare cases it doesn’t, there may be engine-specific tools. If it’s a translated game, the translation team’s hacker will probably have some tools.
3. Converting images/audio
Once you have the images extracted, you’ll still need to resize and convert them to a format VNDS understands (PNG/JPG for images, AAC audio for the DS, OGG-Vorbis audio for Android). If you’re lucky, the output of CRASS will be all in sensible file formats (32-bit BMP/PNG, audio files FFmpeg can read). In that case you can just batch convert the files. Keep in mind to rescale images by a fixed percentage, not to a target resolution (or you’ll accidentally make every sprite as tall as the screen).
Some engines (a disturbing number of them actually) use custom file formats for images and/or audio. They’re usually fairly simple formats like LZW-compressed paletted images or ADPCM-encoded audio with a custom header. Again, if it’s a translated VN, chances are the person(s) hacking it may have tools or info to help you out.
4. Converting scripts
This is the most time-consuming step, especially if you’re not a programmer. It can be done without programming knowledge, but I wouldn’t recommend it unless the script format is particularly simple.
If the script is in some kind of bytecode, you’ll have to decode it first. Even if there’s a translation, they most likely have only had to figure out a fraction of the commands. If you’re faced with a complex bytecode script format — my condolences.
Converting the script basically consists of writing a source-to-source compiler, automatically rewriting one scripting language to another one (in this case, the end result being VNDS code). Don’t try to convert everything in one step, it’s much easier to do things in small increments and write the intermediate results to a file between each step. Small steps are less confusing and it makes tracking down bugs so much easier. The VNDS script format is also horribly limited and this way you’ll only have to look at all the ugly workarounds for missing features (call/or/and) at the very end. All my converters are open-sourced — feel free to take a look through the source code and stare at the horrors.
Packaging VNDS game is pretty easy, just put all the resources in the appropriate folders (backgrounds/foreground/script/sound). For better performance, you can then store the folders in an uncompressed ZIP file with names matching the folders (
background.zip, etc). More documentation can be found on the VNDS wiki.
A: Character encoding
Character encodings are a gigantic pain in the ass. Almost all Japanese visual novel engines use Shift JIS/CP932 for encoding text. VNDS expects all text files, including scripts, to be in UTF-8 encoding.
Shift_JIS encoding in scripts isn’t usually an issue. The real problem lies in filenames using non-ASCII characters and the way those are handled in Windows. Short version: many programs can’t open files with names containing characters outside the current ‘codepage’. The reason so many Japanese games don’t work without AppLocale/NTLEA/etc. is because they use Japanese (non-ASCII) characters in filenames. It’s up to you whether to rename all files to ASCII-only filenames or to deal with the character encoding problem. You should only ever use non-ASCII filenames inside
sound.zip/etc. and never for unarchived resources. VNDS requires filenames to be stored in UTF-8 encoding inside the ZIP file.
B: Supporting multiple screen resolutions
In order to make it easier to create a high-res patch for existing ports, VNDS scripts always assume a resolution of
256x192. Basically, you just port the VN at
256x192, then provide higher-resolution versions of
foreground.zip. See also: Optimizing VNDS ports for Android