Translating a Ghost

Maybe you've seen a cool Ghost that you like, and you want to translate that Ghost into a different language. That's great! Translators really are a gift to any fandom or subculture. I for one deeply appreciate your hard work! But translating a Ghost may seem confusing or intimidating if you don't know much about them. Hopefully, this page will help you figure out how to go about it.

To translate a Ghost, all you need is a text editor. Again, I recommend Notepad++, but any text editor will do, really. What you will be doing is opening the .dic files of the Ghost and then translating the dialogue, while leaving the rest of the coding alone. I'll explain exactly what I mean by this as we go along.

Note: This page is meant for ghosts written in AYA or YAYA. If you open up a .dic or .txt file and nothing in it looks anything like I'm outlining here, then it's written in another scripting language (probably Kawari if I had to guess) and thus I can't really help you. I only really know AYA/YAYA. You might be able to figure a non-AYA/YAYA ghost's dialogue out by applying principles you learn here, but be very careful as you go along.

Now, Ghost dialogue is formatted using something called SakuraScript. You can see a tab for it on the left in the table of contents, no doubt. I highly recommend reading the SakuraScript page once or twice before you start. Learning how to identify SakuraScript will be SUPER helpful to you in separating script from dialogue. It's really not too complicated - all SakuraScript starts with a slash and should be fairly easy to identify, but it might be a good idea to keep the page open as you work.

Getting Ready

Now, the first thing you'll want to do is get to the files of the Ghost you want to translate. If you've read the Walkthrough before, some if this will no doubt seem familiar, but I'll go through it again.

You'll want to open your file explorer and go to the folder where you installed/unzipped SSP. You should see a list of files much like this. You'll want to go into the ghost folder. You'll see an assortment of different folders for the Ghosts you have installed.

Ignore the file renaming here, I'm reusing some shots from the first steps section. Now you're going to want to find the folder of the Ghost you want to edit. Depending on how many Ghosts you have, this might be tricky, but I'm going to take a wild guess that if you're reading this, you probably don't have that many Ghosts. Most of them will have a folder name that will give you some kind of hint of who they are. Hunter and Smoker for example are under "hunter_smoker" and the Girl and Triangle template is under "gt_template". If you can't find it right away, try going into the folders and looking in their shell folders to identify the right one, but hopefully this should not be too hard to do. Once you find the right Ghost folder, open it up.

You should see two folders, ghost and shell. Ghost has the dialogue and coding, while shell has the images. Go into the ghost folder, and you'll see another one called master. Go into that one, and you'll find what we're looking for.

Here are all the coding and dialogue files for the ghost. I'll give you a quick runthrough.

aitalk.dic - the random dialogue for the ghost
anchor.dic - the anchor words for the ghost
bootend.dic - the ghost's boot and close dialogue
commu.dic - ghost communication
etc.dic - extra functions for the ghost
menu.dic - the ghost's menus
mouse.dic - mouse settings for the ghost like for clicking or petting
nameteach.dic - for setting the user's name
shiori3.dic - the hard coding for the ghost, do not touch this
string.dic - customization of the right-click menu
word.dic - unique envelope words

While this probably seems like a lot, remember that all you'll be doing is translating what's already been written by the ghost's creator! You won't have to do any coding yourself or anything like that. Which might not seem like much comfort, but it is a little simpler than when you're making your own ghost.

Also, these are just the .dic files for the template featured on this site. Ghosts that aren't made with this template may have different .dic files, or have named them different things. Usually, they'll have some kind of clue about their purpose in their filename, like aya_battery.dic probably has something to do with the battery of the user's computer. Sometimes the coder will also include commentary or an explanation in the .dic file itself. Don't be afraid to do a bit of investigating if you notice the files don't exactly match up to the template. Even if the files are named differently, the basic concepts should be the same.


I CANNOT emphasize enough how important this is, and here's why. Most ghosts (not all, but many of them) are set up to use Network Update. When a Ghost is set up to use Network Update, that means that when the user tells the ghost to update, it will connect to a remote server, check if its files are different from the ones on the server, and download the right files so the ghost on the server and the ghost on the user's computer match. What this means is that if you tell a ghost that you translated to update, it will check its files against the server copy, see that they're different, and download untranslated files back over them, basically deleting all your work. I don't want that to happen and I'm certain YOU don't want that to happen. So ALWAYS make a backup of your translation somewhere safe.

If a ghost does NOT have Network Update set up, then you do not have to worry about this problem. An easy way to check is to open string.dic, and look for the Network Update URL, usually under On_homeurl { [some url] }. Look at the URL they put in there. If it's a real URL that seems to lead to a real directory set up for that ghost, then it's probably set up for Network Update and you should definitely make back-ups. If it's a fake URL meant as a placeholder or otherwise broken, then the Ghost is probably not set up for Network Update. Although I'd probably still make back-ups just in case.

One thing you can do to make sure that your translation does not get overwritten is to change the Network Update URL in string.dic. This will make it so the ghost can't update remotely anymore, and then your translation will be safe. HOWEVER, you will have to make sure you check with the ghost maker for new updates on your own after that point! And anyone who downloads your translation will also have to come to you for new manual updates.

As you change things, make sure you save and reload the ghost regularly to make sure it still works! You don't want to break anything and not know until it's impossible to find, right? You can quickly reload the ghost through the developer's panel. You can read more about how to unlock that on the first steps page. As a quick summary, you'll want to right click the ghost, go to Options - Preferences, and check the "Enable functions for developers" box. Then you can use Ctrl-Shift-D to bring up the developer panel, or bring it up through right clicking the ghost and going to Utilities - Development Interface.

It looks like this. The "Reload..." button will give you the option to reload various bits of the Ghost.

What to Translate - anchor.dic, string.dic, word.dic

At first, it might be tricky to figure out what to translate and what to leave alone. The easiest place to start will probably be word.dic. Depending on the ghost, you might not even have to do anything with this file. But go ahead and open word.dic in your text editor.

Now, the first thing you'll see (probably) are lines beginning with //. In Notepad++ with code highlighting on (in Notepad++, click Language in the top menu, then C, then C - pic), these lines will turn green. Any line that begins with // has been commented, meaning that it will not be read by the code. Commented lines are just for the coder, or anyone reading their code's benefit. In the template's case, most of the commentary is advice from me to help the person making the Ghost.

You don't have to translate commented lines. You can, if you want to, but keep in mind, the only people who will read them will be other people who open up the .dic files in a text editor and read them. If it'll help you keep things straight, you can translate them, but if you don't want to expend the effort or time, I don't blame you.

//This line has been commented.
//Here I am explaining what this function does.
//--------Function name does a thing-------
Here are some examples of commented lines. While a commented line may do wacky things after the slashes, they always start with two // slashes.

Now aside from the commented lines, you'll see a bunch of things that are formatted like this.


Almost everything in all these .dic files will follow this basic Name {Stuff} format. You can think of these functions as a book if that helps - the Name is the name of the book, the brackets {} are the covers of the book, and the stuff inside the brackets is what makes that book what it is. word.dic has the simplest examples of this, which is why we're starting here. Here's an example of something you might find in word.dic.
Here, we have a function named "color", and inside we have a lot of words in quotation marks. What you'll want to do is translate the text inside the quotation marks. Here, I'll highlight what you would translate in this example.

Just like so. Note:

-Do NOT translate the name of the function. "color" here stays as "color", exactly as originally written.
-Do not touch the quotation marks. Only touch what's inside the quotation marks.

Simple word lists like this are easy - just translate each individual word and replace them. Here's a slightly more complicated thing you might see in word.dic.

"%(username)'s Recycle Bin"
"%(username)'s Document folder"
"%(username)'s secret folder"

I've highlighted again here what you'll be translating. Do NOT translate the function name, and do NOT translate envelopes like %(username), as explained in the SakuraScript page. ONLY translate normal text within the quotation marks.

Because word.dic is mostly composed of simple lists of words or phrases, this file is probably one of the easiest to translate. string.dic is also similarly straightforward, since it's broken up primarily into captions and URLs. Ignore the URLs, just translate the captions. For example...

"Top Menu Option Caption"

"A Site"
"Another Site"
"%ASC(1)" }

You'd leave the URL and coding alone, and just translate the highlighted phrases, whatever they might be. Hopefully, you're getting a clearer idea of what you'll be looking for for translating, particularly if it's something with single one-word phrases.

string.dic has the Network Update URL I mentioned just above. It'd look like...


With a real URL (probably) for the address. If it's a fake URL or otherwise broken, you don't have to worry about your translation being overwritten. If it's a real URL, then you should definitely make back-ups of your translation in case an update overwrites them, or break the URL on purpose as I said above to protect your translation. Remember: a ghost that can't update itself has benefits and drawbacks. Keep them in mind!

anchor.dic is a little stranger, so let's take a look. Again, depending on the ghost, you might not have to touch this. But here's an example.

_talk = reference0
_talk = REPLACE(_talk, "Anchor 1", "\_a[anchor1]Anchor 1\_a")
_talk = REPLACE(_talk, "Anchor 2", "\_a[anchor2]Anchor 2\_a")
_talk = REPLACE(_talk, "Anchor 3", "\_a[anchor3]Anchor 3\_a")
I've highlighted what you'll be translating here. Note that it's ALWAYS in quotation marks! Quotation marks are your greatest friend for showing you what to edit.
when "anchor1"
"\0\s[0]This dialogue is for when Anchor 1 is clicked.\e"
Down below in the OnAnchorSelect function, you'll again see dialogue in quotation marks. You'd translate what I have highlighted. Not every ghost uses anchors. Each ghost is different! But hopefully you're getting sort of an idea of what you're looking for.

What to Translate - Ghost Dialogue

You can find ghost dialogue in almost any file, really, but let's look at some dialogue you might find in aitalk.dic, where all the ghost's random dialogue is stored. aitalk has a lot of dialogue all stored under one function, RandomTalk. It looks sort of like this.
RandomTalk : nonoverlap
"\0\s[0]This is a single line of dialogue for the main character. There is no response.\e"

"\0\s[10]This is a single line of dialogue for the side character.\e"

"\0\s[0]This is a two line piece of dialogue.\w8\1\s[10]This is the second line.\e"

And so on, and so forth. These bits of dialogue are usually relatively straightforward. Again, having some familiarity with SakuraScript will help you here in identifying what's a tag and what's dialogue.
"\0\s[10]This is a single line of dialogue for the side character.\e"
Here's a simple line. I've highlighted what you would translate.
"\1\s[10]This is a two line piece of dialogue.\w8\0\s[0]This is the second line.\e"
Here's a slightly longer line of dialogue that passes between the two characters. Note that you're not touching the code. You're just translating the actual text.
"\0\s[0]This is a three-step piece of dialogue.\w8\1\s[10]Here is the response.\w8\0\s[0]\n\n[half]Here is the third step.\e"

"\0\s[0]This is a long piece of dialogue.\w8\1\s[10]This is my first response.\w8\0\s[0]\n\n[half]This is my response to that.\w8\1\s[10]\n\n[half]This is my second response.\w8\0\s[0]\n\n[half]And this is my last response.\w8\1\s[10]\n\n[half]This is my final word.\e"

"\1\s[1239]\i[3]%(chargername), don't you know something about this??\w8\p[3]\s[1240]\b[8]Being turned into an eggplant? \w8No, I can safely say I have little experience in this area.\w8\1\s[1239]\n\n[half]Then how are we supposed to turn back?! \i[8]What are we going to do?!\w8 \w6\0\s[1238]\i[5]Man alive, you need to calm down.\w8\1\s[1239]\i[2]\n\n[half]How can I calm down when we're eggplants?! I have no arms! We all have no arms!\w8\p[3]\s[1240]\b[8]\i[4]\n\n[half]I'm sure there's a reasonable explanation.\w8\1\s[1239]\i[3]\n\n[half]Aaaaa what happened to your legs?!\e"

As you can see, even with long pieces of dialogue, it's the same basic pattern. Leave the SakuraScript alone and just translate the dialogue. Don't go reformatting the line with line breaks or anything either, the ghost's original coder already took care of that. Just translate the text.

Now, what if the line has some SakuraScript inside it?

"\0\s[5]In this dialogue, I will go from happy \s[4]to sad.\e"

"\0\s[0]I am pausing \w4for dramatic \w6emphasis. \w8P\w6 - \w6A - \w6U - \w6S - \w6E.\e"

"\0\s[0]Emptying the recycle bin.\w8\1\s[19]I'm going.\w8\w8\s[-1]\w8\w8\w8\w8\w8\![raise,OnGarbagecanEmpty]\w9\w9\w9\1\s[10]\cDone.\e"

Just work around the SakuraScript as best you can.
"\1\s[10]Here is dialogue using %(username)'s pronouns.\w8\0\s[0]%(heshe) went to the store and got %(himher)self some milk for %(hisher) cat.\e"
One of the tricky things that may be hard to work with is the pronoun feature some ghosts have, where the user can select a pronoun for the ghost to use for them. Some languages don't use pronouns the same way... in that case, you may have to rewrite the sentence to make sense without using the pronouns. These are tough calls to make. But not every ghost uses pronouns! So you might not even run into this problem, depending.

As you look around aitalk.dic, you may see other functions that have other words in them. Here's an example from my Hunter/Smoker ghost.

chargersleeping = "off"

"\p[3]\s[1214]\b[8]Zzz... \w8mgh... \w8no... \w8NO-!\0\s[1194]%(chargername) WAKE UP! \p[3]\s[1220]\b[8]\n\n[half]!!! \w6\0\s[63]\p[3]\s[1218]\b[8]\i[8]What, what happened?\w8\1\s[1211]\i[18]\i[23]You were asleep, %(chargername)! Thought maybe you'd want to wake up and join the party again, haha. \w8\p[3]\s[1245]\b[8]\i[10]\i[41]\i[26]\i[35]\n\n[half]Asleep... \w6hmm.\e:chain=end"
Notice the "chargersleeping == "off"" at the top there? If you see words like that in a function with operators (more on operators in the coding section), don't touch them! Don't translate them or edit them in any way. The ghost's coder is using variables and values to do different things. ONLY translate what looks like spoken dialogue that's within quotation marks. Leave everything else alone.

What to Translate - Menus and Choices

A straightforward line of dialogue is relatively simple to translate, but what about menus? These can be trickier. First, let's look at how SakuraScript formats a choice in a menu.

\q[Displayed Name,actualfunction]

The Displayed Name is what you actually see in the menu when you click the ghost or what have you. The actualfunction is the name of the function that choice will run when it is clicked. You want to translate the Displayed Name and NOT the actual function. Here's an example.
"Hey, what's up? Can you say something to me? \q[How are you?,sayinghello]\e"
I highlighted the relevant parts. Notice how you only translate the first part of a choice, and not the second! This is pretty much the only time you'll mess with a SakuraScript tag, so be careful as you do this. Here's Triangle's menu from the template with the proper highlighting.
"This is a menu introduction dialogue."
"This is another menu introduction dialogue."
"This is the third menu introduction dialogue."
"This is the fourth menu introduction dialogue."
"\n\n[half]/ \![*]\q[Update,keroupdatecheck]\n/
\![*]\q[Bug report,bugreport]\n\n/
\![*]\q[Test variable,testvariable]\n\n/
As you can see, just as we've been doing so far, we ignore the SakuraScript and translate only what's in the quotation marks. And you can see that you only translate the first part of each menu choice as you go down. Hopefully this gives you an idea of how menus work.

Testing your new dialogue

As you go through the files, make sure you save and reload the ghost regularly to make sure you aren't breaking anything! I already said this but I just want to say it again. To test the new dialogue you wrote, it depends on where it is. Random dialogue can usually be called by asking the ghost to say something in their menus, or by clicking them once and then hitting "t" on your keyboard, although it might be different for each ghost. Their readme may tell you what key forces dialogue. Dialogue that's called for random functions, like when checking mail or what have you, can be checked by running those functions. However, you can also use Script Input to check dialogue. Script Input is an option on the Developer's Panel, which I talked about further up the page. Here it is again.

You can see it's the top button, and you can also use Ctrl-S to bring it up. It'll bring up a little input box. Paste your new dialogue into there. So if you had a line that read:

"\0\s[2]This is my surprised pose.\w8\1\s[12]We are shocked!\e"

You would paste \0\s[2]This is my surprised pose.\w8\1\s[12]We are shocked!\e into the input box. This time, you include everything inside the quotation marks. Click ok or hit enter, and the ghost should read the dialogue just like it was saying it normally. While this probably isn't as big a deal for a translator as it is for someone doing ghost dialogue from scratch, it's probably not a bad idea to test your new dialogue and see how it looks.

Distributing your translation

Now, let's say you went through and finished editing all the ghost's files. Phew! Now you want to share those files with others. First, make sure you make back-ups of your translated files just in case. You can't be too careful, you know. You can also write a new readme file about your translation you can include with it, with stuff like your name, how to contact you, where to get the original ghost, stuff like that.

There are a few different ways you can get these files out. One fairly straightforward way would be to just select all the .dic files you translated and zip them all up into one zip file. Then you would upload that zip somewhere as a translation patch for the ghost. The user would then have to get the zip, unzip the files, and then replace the .dic files of their untranslated ghost with your translated copies. Not terribly complicated, but make sure you write out clear directions for whoever downloads the zip so they know how to use it.

You could also do a broader variant of this by just zipping up the entire SSP folder, your translation files included, and then distributing that. This means that whoever downloads this zip will get all the ghosts you've downloaded, with all the history and preferences you personally set for those ghosts and SSP itself. Most English ghosts I've seen do this. While it's efficient and easy for the user, since they just have to unzip the file and run SSP, you can end up with a whole bunch of copies of SSP that you don't really need, and you'll have to find each copy when you want to run a different ghost, instead of being able to just switch to a ghost within the program itself. But really, it's a matter of preference.

Another method would be making a .nar file of the translated ghost. A .nar file is basically a zip file that's associated with SSP and ghost programs in general. When people drag and drop a .nar on their current ghost, the ghost will install whatever's in the .nar automatically. In general, I would do this if you're assuming people aren't going to have (or be using) the ghost in the original language already.

To do this, first, if you haven't made a .nar before, you'll want to right click the ghost and go into Options - Preferences. Check "Enable functions for developers" box in the window that comes up. Then click the "Dev./Other" tab in the preference window. If "Create Update Def. File and/or NAR at Directory Drag & Drop" is not checked, check it then close the window.

Now, you'll want to go back into your file explorer, and find the folder for the ghost. This would be the main folder, like "hunter_smoker" or "gt_template" like you found before at the beginning of this. You'll want to drag that folder onto the currently running ghost. It should pop up this window at you.

Most of these options are for developers who are setting up for Network Update, so you don't need to worry about those. What you want is the "Create Nar" option. This will package up the whole ghost with your newly translated .dic files into a .nar, which is the usual distribution method for a ghost.

The ghost will ask you where you want to save the .nar file, and what you want to call it. I would give it a name like "ghost-translation". So, if you translated Emily, the default SSP ghost for example, I would save the .nar as "emily-english.nar" or something like that.

Save it and then upload the .nar somewhere for people to download. When people use your .nar to install the ghost, it'll install the ghost like normal but with your translated files instead of the original text. This might run into problems if they already have the ghost installed in the first language... for example, if you had Hunter and Smoker in English, and you installed a .nar for them in Japanese, they might have a directory conflict. Then again, I think SSP has updated enough so that it'll warn the user if two directories will overlap, and give them an option to put it in a new directory. So, this might not be a HUGE issue. But it might be something to be aware of.

If the ghost seems to update itself regularly, or at least occasionally, you might want to date your translation so users know when you released it and what version it corresponds to. I talked about how it'll overwrite your translated files if the ghost tries to update itself, which is discouraging, I know. But on the other hand, if you saved your backups, all you have to do is go into the updated ghost's files, find the new stuff, translate it, replace the rest with your backup, and then zip up and distribute your updated translation. Notepad++ actually has a plug-in that compares two files which can help you find new stuff.

If you suspect a ghost you translate might update in the future or has been set-up so it can update, make sure to warn anyone who might use your translation not to tell the ghost to update! Your user doesn't want to lose your hard work any more than you do.

That's all I can think of for now...

<--Phase 6 - Publishing your Ghost