An English fan translation of Sentimental Graffiti (NEC Interchannel, 1998,
Sega Saturn, T-20106G), a dating sim about twelve girls scattered across
twelve Japanese cities. It was never released outside Japan, and as far as we
can tell nobody had attempted this before - there was no existing toolchain for
any of the game's file formats.
The game ships on two discs. This repository currently covers disc 1: its script is 100% translated - 21,216 player-facing records across all twelve routes - and it builds and boots.
Disc 2 has not been ripped yet. Everything is namespaced by disc so the two
never collide: translations live under translation/variants/en/disc1/, and
every tool takes --disc=disc1 (the default) or --disc=disc2. Do not assume
disc 2 matches disc 1 - check its own TOC, since it may well reuse the same
script filenames.
This repository contains no game data whatsoever. No disc image, no extracted script, no font, no executable, no BIOS. Everything here is either our own code or our own English prose.
To use any of it you need a legally-obtained copy of the game - ideally your own physical disc, which you rip yourself. The tools read your disc and write your patched image. Nothing is redistributed.
The same goes for the Sega Saturn BIOS, which Mednafen needs in order to boot anything. We do not link to one and cannot help you find one.
What you supply, and where it goes (all of these are in .gitignore):
originals/disc1/ files extracted from your own disc (script.pak, font.pak, 1st.bin, ...)
iso/ your rip: disc1.bin + disc1.cue, and the patched images the tools write
bios/ your Saturn BIOS (Mednafen wants ~/.mednafen/firmware/sega_101.bin)
extract/text/disc1/ regenerated by tools/scr.py - contains the original Japanese
script, which is why it is never committed
build/ patched font.pak / 1st.bin produced by the tools
Everything in this repo is designed around that boundary: the English lives in
translation/variants/en/disc1/ as a plain {record index → English} map, carrying
none of the original text. It is meaningless without your disc, and that is
deliberate.
| Path | What it is |
|---|---|
tools/ |
The whole toolchain: archive reader/writer, script parser, UI-string extractor, translation database, font editor, renderer patcher, dead-memory prober, offline preview renderer, CD sector maths |
translation/variants/en/disc1/ |
The English translation for disc 1 - 37 script files plus 13 UI_* files for the interface |
docs/VOICES.md |
Dubbing the voice track - optional, two engines, the tonal layer |
translation/voice/ |
Cast and delivery direction: who each girl is, her accent, how each line lands |
translation/voice/manifest.json |
The clip map - all 10,405 voice clips: id, the English line, the script records it is spoken at, and the filename to save your own recording under |
PITFALLS.md |
Read first. The log inverted - organised by what you are about to do, so the trap is visible before you hit it |
translation/STYLE.md |
The style guide: cast table, per-character voices, laugh registry, locked terminology |
docs/SETUP.md |
Linux setup, software requirements, emulator, BIOS |
docs/PIPELINE.md |
Rip → extract → translate → build → test, end to end |
docs/FORMATS.md |
Every file format we reverse-engineered |
docs/FINDINGS.md |
The interesting discoveries, including five bugs in the 1998 original |
CLAUDE.md |
Project instructions Claude Code reads automatically |
.claude/ |
Permissions plus slash commands: /status /build-disc /verify-burn /preview |
PROMPT.md |
A prompt to hand to Claude Code to pick this up from scratch |
LOG.md |
The full project log, warts and wrong turns included |
- Read
docs/SETUP.mdand install the prerequisites. - Rip your disc (
docs/PIPELINE.md- it is a mixed-mode 3-track disc, so a plain.isois wrong and will not work). - Extract the archives, then regenerate the script extraction.
tools/textdb.py disc en iso/disc1.bin iso/disc1_en.bin --fullwidth --cols=42tools/uistr.py extract, thentools/patch_1st.py disc en ...for the interface (docs/PIPELINE.md§7 - read the warnings, they each cost a broken build)- Boot the result in Mednafen.
Two things this is deliberately set up for.
A different translation. translation/variants/en/disc1/ is a plain
{record index → English} map, and a variant can name another as its base
and override only the lines it disagrees with. So a new tone, a more literal
pass or a different name romanisation is a new directory, not a fork:
tools/textdb.py bilingual en review/ # Japanese and English side by side
tools/textdb.py check mine # control codes, box limits, budgetsbilingual is generated output for reading - the Japanese and the English stay
in separate files so that neither can be edited by accident.
A different dub. You do not need our engine, our cast or an API key. Every
clip has a stable filename derived from its id - VO_HON0/002.wav - listed in
translation/voice/manifest.json with the line it says. Fill a directory with
those names, from any source including real performers, and:
tools/relayout2.py build en iso/disc1.bin out.bin --wav-dir=mydub/Clips you leave out keep the original Japanese, so you can do one girl and play
it. See docs/VOICES.md → Bringing your own audio entirely.
Clone, cd in, and run claude. It reads CLAUDE.md automatically - the
formats, the constraints, and the ground rules this project learned the hard
way. Four slash commands are set up:
| Command | Does |
|---|---|
/status |
translation coverage and validation |
/build-disc |
build a patched image and boot it in Mednafen |
/verify-burn |
compare a burned disc against its image (do this before the console) |
/preview |
render text boxes offline using the game's own font |
Read-only tooling is pre-approved in .claude/settings.json; anything that
writes to a physical disc will ask first.
PROMPT.md has a longer starting prompt and a list of what to tackle next.
The English ships as a bare {record index → English} map, which is safe to
redistribute but awkward to proofread - you cannot see what the Japanese
actually said. So the tooling generates a side-by-side file from your disc:
python3 tools/textdb.py edit en COMMON # -> edit/disc1/COMMON.json
# ... fix the "en" fields in your editor ...
python3 tools/textdb.py absorb en COMMON edit/disc1/COMMON.jsonEach record shows jp, en, the record type and the voice cue. Edit the
English, absorb it back, and the validator runs before anything is saved - it
will refuse the write and tell you which record is wrong if you drop a $C,
change a menu's option count, exceed a box budget or introduce a character the
font cannot draw.
edit/ is gitignored: those files contain the original Japanese, so they are
yours and stay on your machine. That is also why the Japanese is not committed
here - anyone with the disc can regenerate it in one command, and anyone
without it has no business having the script.
98% translated across script and interface, and playable end to end in an emulator.
Done: the script, fully translated and validated. .pak and .SCR formats
decoded with byte-identical round-trip tests. Font format decoded - including a
second 16x12 font nobody expected, which is what draws Latin in menus. A
four-instruction SH-2 patch that halves the dialogue advance and doubles the
line budget, plus narrow Latin glyphs.
The interface too: all 160 location and city names, the main menu, the options screen and its help lines, all 64 profile-card fields, the save/load screens, the calendar and weekdays, the travel map, job names, and all 120 tourist guide blurbs re-flowed into their fixed 16x4 grid.
The full English script is ~2.35 MB against a 1.54 MB slot, so relayout.py
rebuilds track 1's layout to make room and trim_avi.py shortens the opening
FMV by 2.4 seconds to buy the last 500 KB - both verified, both reversible.
Not done: 68 sound-test track titles, and the 232-line staff roll (deliberately out of scope). Disc 2 has not been ripped.
Cannot be done as text, and documented rather than attempted:
- The girls' given names are three characters each. They live in a 26-byte
per-girl record that also holds affection and flag data, and eleven of the
twelve are reached by computed address with no pointer to rewrite. Widening it
is specified in
docs/FORMATS.md; the failure mode is silent save corruption. - FMV captions are bitmaps in
telopcg.pak, a different archive format. - The opening FMV is Duck TrueMotion 1, which ffmpeg decodes but cannot encode.
Tools and documentation: MIT (see LICENSE). The English translation text is
released under the same terms. None of this grants you any rights to the
original game, which remains the property of its owners.