This is part 1 of a 3 part series, probably...
| Part | Title |
|---|---|
| 1 | Translating a 1998 Japanese Visual Novel on Sega Saturn I Bought by Accident |
| 2 | Translating a Japanese Sega Saturn Game From 1998: The User Interface |
| 3 | ...incoming |
This is all new to me.
I haven’t done this kind of reverse engineering before, I don’t read Japanese, and I didn’t set out to translate a Sega Saturn game.
I just bought something I didn’t understand and kept going long after it would have been reasonable to stop.
There’s a trader at my local market who’d just got back from a trip to Japan.
He doesn’t do it regularly. This was a one-off as far as I can tell. He had come back with boxes of games: SNES, N64, PS1, all of it in Japanese.
Most of it had already been picked through by the time I got there.
What was left were two Sega Saturn games.
I assumed someone else had already taken anything worth having.
I bought them anyway.
One of them was Sentimental Graffiti (1998), what I later learned is a dating sim.
The game never left Japan, it isn’t especially well regarded (I don't think?), and I don’t have any particular interest in the genre.
Naturally, I tried to play it.
I rummaged through boxes until I found my old Sega Saturn, dug out the cables, and dusted off the Trinitron CRT that had been sitting around waiting for exactly this sort of unnecessary exercise.
There was something oddly satisfying about putting a 1998 Japanese game into the original hardware it was made for.
Obviously I couldn’t read a single thing.
The first thing the game asks you to do is enter your name.
Every label on the screen is in Japanese, including the instructions for using the grid.
It goes without saying, this is as far as I got 😂.
At that point, the sensible thing would have been to stop.
Instead, I realised how much dialogue the game would likely contain and wondered whether it would be possible to extract it and translate it instead.
It's not something I would have considered in the past, but with AI now available to assist us, I thought this would be an interesting experiment.
Step 1: Let Claude loose on the disc
This genuinely surprised me.
There isn’t a toolchain for this game. No documentation, no format notes, nothing describing how the data is organised.
Normally, this is where you would start digging through forums, hunting for old reverse engineering notes, writing scripts, and slowly building up an understanding of the file formats.
Instead, I copied the contents of the disc onto my Linux machine and asked Claude to start looking through it.
I honestly didn’t expect much.
But Claude started finding structure.
It identified blocks of data that looked like text, repeated patterns that appeared to be framing information, and encodings that were likely to be Shift-JIS.
If you know what Shift-JIS is, congratulations. You are already much further down this particular rabbit hole than I was.
I had never heard of it.
It turns out Shift-JIS is a character encoding that was widely used for Japanese text. In simple terms, it is a set of rules that tells a computer how to turn stored bytes into readable characters.
The game doesn’t store text as something obvious like:
Hello, my name is...
It stores numbers that need to be interpreted correctly before they become the Japanese characters you see on screen.
Without understanding that mapping, the dialogue is just a pile of meaningless bytes.
From there Claude began separating large portions of the script from the rest of the disc contents.
It reduced the problem from:
"Understand everything on this disc"
to:
"Find the parts that look like dialogue"
The fact that I could copy a Japanese Sega Saturn disc onto a Linux machine, point an AI at it, and have it start making sense of the contents was, frankly, a little ridiculous.
And that was the moment this particular idea started feeling possible, and the rabbit warren I was about to disappear into began to reveal itself.
Step 2: Find the letters
The game carries its own font - every character it is capable of drawing, stored as raw pixels with no header and nothing to say which picture belongs to which character.
Before you can change any text, you have to work out that mapping.
Claude worked it out, and we tested it in the most direct way available: take the five most common Japanese characters in the entire script, redraw them as big obvious Latin letters, rebuild the disc, and see what the console does.
The screen we tested it on was, appropriately enough, the one that had stopped me on the first day: the name-entry grid.
I turned the disc back on, reached the same screen that had been completely unreadable a few days earlier, and it came up on the CRT looking like this:
A B, a D and a C sitting exactly where three Japanese characters should be.
It is not much to look at - but it meant the font mapping was correct, the disc could be rebuilt, and the Saturn was drawing something I had changed!
A 30(odd)-year-old console, running a game that had never been designed to display English, was now showing my characters on screen.
Step 3: Pull the script out into JSON
This was the point where the disc stopped looking like a mysterious black box.
I knew, obviously, that games were made from code and data. I have been writing software for a long time.
What I had never done was take a finished game from 1998 and start pulling apart the layers inside it.
The script turned out to be stored in plain Shift-JIS, wrapped inside a small repeating structure in the game's bytecode.
If that sentence makes you think "what the heck does that mean?", you are not alone.
The important bit was that we could now extract it.
The dialogue could be pulled out into ordinary JSON files. One file per script.
21,321 records in total.
Here's what the opening conversation looks like after extraction:
{
"file": "COMMON.SCR",
"records": [
{
"i": 3,
"type": "dialogue",
"jp": "$C:ご、ごめん、沢渡…$n その、最近あまり会いにこれなくて"
},
{
"i": 4,
"type": "dialogue",
"jp": "ほのか :別に… あなたに会えなくたって$n 私、なんとも思わないもん",
"voice": "VO_HON0"
},
{
"i": 5,
"type": "dialogue",
"jp": "ほのか :嘘…$n ホントはちょっと寂しかった",
"voice": "VO_HON0"
}
]
}
A few things that I learned along the way:
-
$Cis the player's name. The game substitutes it at runtime, so it appears wherever the protagonist speaks. -
$nis a line break. The spaces after it are the original developers manually aligning the dialogue underneath the speaker's name. -
voiceis the sound clip that plays with the line.
The voice information turned out to be particularly interesting.
The filenames on the disc are not always telling the truth.
Every dialogue file actually contains the person after the one named in the filename.
That was discovered because Claude's translator looked at one of the extracted lines and said:
"That isn't Honoka. That's Taeko in Aomori."
The voice files agreed.
The translations are kept separately from the original Japanese:
{
"file": "COMMON",
"variant": "en",
"lines": {
"3": "$C: S- Sorry, Sawatari... I know I haven't been able to come see you much lately",
"4": "Honoka: It's fine... It's not like I miss you when you're not around or anything",
"5": "Honoka: That's a lie... The truth is, I was a little lonely"
}
}
Keeping these separate turned out to be one of those things that seemed like a technical detail at the time, but became really important.
The Japanese extraction is the source material. It can always be regenerated from the disc.
The English is just another layer on top.
That means a completely different translation, a different writing style, or even a full rewrite of the dialogue could exist alongside it without touching the original extraction.
The English is stored as plain text. The line wrapping is handled later when the game is built.
That turned out to be a very lucky decision for reasons that became obvious in the next step.
Step 4: English is too wide
The game assumes every character fits into a fixed square.
That works fine for Japanese.
It doesn’t for English.
The dialogue box supports 21 characters × 3 lines, and the renderer treats each character as the same width. So instead of flowing text, English gets forced into rigid blocks.
I wasn’t going to play through the entire game just to find overflows, so I built a previewer.
It renders the translated text using the game’s font and layout rules, then flags anything that spills over.
Every red section is text that no longer fits inside the original dialogue box.
The results weren’t great.
1,016 of 3,663 dialogue boxes overflowed - about 27% of the game.
At first glance, it looks like a translation problem.
It isn’t.
The issue is spacing.
The original renderer treated every character as a fixed-width square. That works perfectly when every character is roughly the same size.
Japanese:
す み ま せ ん
English:
S o r r y
Each English letter is being given a full character cell. So a short word like “sorry” burns through five.
The game doesn’t need shorter text.
It needs variable-width characters.
Step 5: Making the letters narrower
Fixing this meant changing the game's own code.
Somewhere inside the Saturn executable was the routine responsible for drawing a character and moving the cursor ready for the next one.
So Claude disassembled the executable and started looking for it.
The disassembly revealed something important: the font was actually 24×12 pixels, stored in a different format than we first expected.
The original CRT test had appeared to confirm the earlier assumption. We had changed glyph data, rebuilt the disc, and watched the Saturn draw the result.
The chain worked, but the assumption underneath it was wrong.
The test proved we could change the font. It didn’t prove we fully understood the font.
Once the drawing code was understood, the fix was surprisingly small.
A handful of bytes changed how far the cursor moved after each character - moving half a character width instead of a full one - and allowed twice as many characters per line.
That almost solved it.
Loaded into the emulator, the letters were finally the right size and the spacing was correct.
But every line of dialogue still stopped halfway across the box.
The letters are right. The line isn't. The whole right half of that box is doing nothing.
The patch had changed how wide the letters were. It hadn't changed the code deciding where lines break.
That was still wrapping English at 21 characters — because 21 was the correct limit when the box could only hold 21.
It holds twice that now.
This is where storing the English without any line breaks paid off. It looked like a fussy detail at the time, but it meant the wrapping could be fixed during the build process instead of rewriting thousands of translated lines.
Same text, same box, using all of it.
The overflow measurement that previously showed 27% of boxes failing now shows 0.4%.
Fifteen boxes in the entire game still need attention, and those are simple text adjustments.
There was also one more useful discovery.
Could longer dialogue simply continue into another text box?
It turns out the game already knows how to do that.
Consecutive lines naturally chain into another box without needing any extra code.
So if a translation needs more space, the build process can split the line automatically.
Step 6: Translating all of it
With the last technical unknown out of the way, all that was left was volume.
Thirty-seven script files. Every line of dialogue, every choice menu, every location label.
Every batch went through a validator before it was allowed back in. Control codes counted, choice menus checked for the right number of options, nothing over the box budget.
The only Japanese left is 105 records belonging to the developers' own debug menu, which no player will ever see.
I want to be careful with that sentence, though, because for a while I was quietly reading it as "the game is translated".
It isn't. The script is the dialogue. The dialogue is not all of the text.
I'll come back to that, and I promise it's funnier than it sounds.
The problems that showed up at this scale were not the ones I expected.
Nobody warns you that English runs out of ways to giggle.
Twelve people share a handful of Japanese laugh sounds between them. By the seventh character, every natural English spelling had already been taken by somebody else.
"Heehee". "Hehe". "Heheh". "Hehehe". "Ahaha". "Haha". "Teehee".
Four translators working on the same person at the same time each invented a different laugh, and every one of them was a perfectly sensible decision made in isolation.
So there is now a laugh registry in the style guide. An actual table, of who laughs how, that has to be consulted before anyone is allowed to invent a new giggle.
I did not have "maintain a giggle database" on the list of things this project would involve.
Then there was the thing you can only notice by translating every route at once.
The entire premise of the game is a single unsigned letter that says "I want to see you", and the whole journey is about working out which of the twelve people sent it.
Every single route reveals its own person as the sender.
Two of them even share the same scene, word for word in the Japanese.
A player in 1998, finishing one route, would simply have learned that it was her. Reading all twelve at once is the only way to find out that the game's central mystery was never meant to have an answer.
Twenty-eight years, and possibly nobody noticed, because who would sit down and read all twelve?
Well. Quite.
Step 7: Two seconds of the opening movie
Then the translated script had to go back onto a disc, and the disc said no.
The English script is bigger than the Japanese one it replaced, and a 1998 disc has no spare room on it. The files sit end to end, in the order the game expects to find them, with nothing wasted anywhere.
Everything after the script had to shuffle along to make space, and even then it didn't quite fit.
So the opening movie gave up half a megabyte out of 33, which works out at roughly two seconds off the end of the intro.
I did not expect this project to involve cutting two seconds off a video to make room for words.
But it's a decent illustration of what a finished 1998 CD actually is. A fixed amount of physical space, entirely spent, by people who had no idea that somebody would be back twenty-eight years later asking for a bit more.
Sorry about your ending, whoever animated that.
Step 8: The game reviewed our translation
The first complete English build put a message on screen that we had not written.
「インフォ窓のメッセージが溢れました」
The info window's message has overflowed.
That is not our error handling.
That is the original developers' own assertion, left in the retail game, firing for what may well be the first time in its life.
The info window is the small box that displays location names. It was sized for Japanese labels of at most nine characters.
Ours included "Hiroshima Museum of Contemporary Art".
Thirty-six.
Ninety-four location labels got shortened. The longest is now twelve characters, along the lines of "Bot. Garden" and "Mt. Hakodate", so they read like map pins, which is roughly what the Japanese ones were doing anyway.
A debug check written in 1998 caught a defect in a translation written in 2026, and told us exactly what was wrong, in Japanese, the moment we broke it.
We had been carefully validating every line against the dialogue box, because that was the box we knew about.
Nobody had mentioned that the info window was a completely different and much smaller thing.
Nobody except the game, which had been sitting on that error message for twenty-eight years waiting for somebody to be daft enough to trigger it.
The debug message
Step 9: On the actual console
Everything up to this point had been proven on a computer.
The emulator is an enormous convenience. Rebuild the disc, reset, and you're looking at the result in seconds instead of burning for twenty minutes and walking across the room.
But it is still a program agreeing with another program.
The console is the part that doesn't care what you meant.
So: burn the rebuilt disc, carry it over to the Saturn, put it in, and try not to hover.
It works.
The script, in English, running off a disc, on the original 1998 hardware, on the same CRT that had beaten me at the name-entry screen a few weeks earlier.
Photographs of a television, because a screenshot wouldn't have felt like proof.
I have been staring at these for considerably longer than is reasonable.
Everything in this article is in those photographs. The handful of bytes that let letters be narrow. The script that came out as JSON and went back in
And then you press a button, and half the menu is still in Japanese.
Step 10: The text that isn't in the script
This is the bit I had wrong, and seeing it on a television is what corrected me.
The dialogue is translated but the dialogue was never the whole game.
Everything the player does between conversations is interface. Travelling to another city. Taking a part-time job to afford the train fare. Reading a girl's profile. Checking what day it is.
None of that text lives in the script files at all. It sits inside the game's executable as loose Japanese strings, scattered through the code that uses them.
There are 1,361 of them, about 13,659 Japanese characters.
I have translated seventeen.
Those seventeen are the name-entry screen, which I did on the first afternoon, because it was the screen that had stopped me and I was taking it personally.
Obviously I still needed to get past this screen, so hacked this together😂.
Everything else is untouched. The main menu. The job list, which is far more charming than it needed to be: apple orchard, ski resort, dishwashing, dock work, soba shop, takoyaki stand. Every girl's profile card, with her birthday, star sign, blood type and school.
And then there's the travel guide.
I didn't know there was a travel guide. Every location in the game has a written description attached to it, in the register of an actual guidebook. The one for the Saikai Bridge mentions that you can walk across it, but that people afraid of heights might prefer not to.
Nobody in 1998 had to write that. Somebody did anyway, for a dating sim, and then it sat there unread for nearly three decades until somebody who can't read Japanese counted it.
The dialogue, it turns out, was the easy text.
It lives in a container built to hold lines of varying length, so English can be whatever size it likes. That was the whole point of the round-trip test right at the beginning.
These strings have no container. Each one sits in a fixed hole in the executable with the next one immediately behind it, so a translation has to physically fit in the space the Japanese was using.
"Part-time Job" is considerably longer than アルバイト.
So what's left is a slot-by-slot fitting exercise across thirteen thousand characters of menus and travel writing.
Less glamorous than cracking a script format. Just as necessary.
If you want to try this yourself
There's one file on GitHub, and it's the one I'd actually point at:
https://github.com/joebuckle-dev/sentimental-graffiti-translation-claude
That's CLAUDE.md, the guide the whole project runs on. Not the tools, not the extracted script, not the translation, and definitely not the disc.
To be completely clear about that last part: there are no ROMs, no disc images, no BIOS files and no game data of any kind in there, and there never will be. It is a text file about how to think about a problem. Anyone wanting to do this to their own game would need their own disc and their own BIOS, which means owning the thing, which means finding it, which is its own adventure. Mine came from a folding table at a market.
The guide itself isn't really instructions so much as everything we got wrong, written down so it couldn't happen twice.
There's a table in it of mistaken conclusions. The disc that turned out not to be damaged. The USB port that was never the problem. The font format that was confidently recorded as verified and was wrong for a day and a half.
It is essentially a list of things I was sure about and shouldn't have been.
Which is probably the most transferable lesson here, and has very little to do with Sega Saturns.
It isn't finished
I should be straight about where this actually stands, because "I translated a game" is doing a lot of work in that headline.
The dialogue is done and it plays on the console. The menus, the profiles and the travel guide are all still in Japanese.
The translation itself has never been played end to end. Twenty-one thousand lines were checked by a validator, not by a human reading them in context, and I am fairly confident there are lines in there that are wrong, or stiff, or coming out of the wrong girl's mouth.
Two seconds of the opening movie are gone, and they're not coming back.
A stock Saturn still can't boot it at all, because the copy protection is physically stamped into a pressed disc and there's no way to write it. Mine needs a boot cart to get past that. Everything after that point is the game itself, running our data.
For the avoidance of doubt: I own the game. Both discs, bought from that market stall, sitting on the shelf next to the console. Everything here came off my own copy, and nothing is going anywhere else. This is a translation of a game I own, for the game I own, played on the hardware it shipped for.
And there is a whole second disc I haven't touched.
So it is playable in English, and it is not finished in English, both at the same time. I didn't expect that to be a distinction I'd have to make.
I bought this game because it was the only thing left on the table.
I still have no particular interest in dating sims, and I still can't read a word of Japanese.
But there is a Sega Saturn in the corner of the room playing a game in English that has never been in English, and I now understand every single layer of how it got there.
Which was not the plan. There was no plan.
I'll write part two when disc two is done.











Top comments (0)