Ren'Pyでゲームを作っていると、こんなことに気づくかもしれない。
play music "戦闘BGM.ogg"
日本語ファイル名が、普通に通る。エラーも出ない。
「じゃあ日本語ファイル名で管理すれば楽じゃないか」と思うかもしれないが、結論から言うとやめたほうがいい。この記事では、なぜ動くのか、なぜ危ないのか、そして安全な代替手段を解説する。
結論:動くが非公式
Ren'Py 8.5.2 では、画像・音声・動画のファイル名に日本語(非ASCII文字)を使っても、多くの環境で動作する。
ただし、これは Ren'Py が公式にサポートしている機能ではない。Ren'Py の作者である Tom Rothamel(PyTom)は、Lemma Soft Forums で一貫して次のように述べている。
ファイル名には ASCII 文字だけを使うべきだ。それが配布とクロスプラットフォーム互換性を大幅に楽にする。
公式ドキュメントにも、Unicode ファイル名が正式にサポートされているという記述はない。
なぜ動くのか:Python 3のUnicode処理
日本語ファイル名が通る理由を理解するには、Python の歴史を少し知る必要がある。
Python 2 時代(Ren'Py 6.x / 7.x)
Python 2 では、文字列はデフォルトでバイト列(str = bytes)だった。日本語を扱うには u"" プレフィックスで明示的に Unicode 文字列を作る必要があった。
# Python 2 — これはバイト列
"戦闘BGM.ogg"
# Python 2 — これがUnicode文字列
u"戦闘BGM.ogg"
Ren'Py 6.x では、音声ファイルの内部処理が C 関数に char* 型で渡されていたため、Unicode ファイル名は UnicodeEncodeError でクラッシュしていた。この問題は 2014年に修正 されたが、根本的に Python 2 の文字列処理には限界があった。
Python 3 時代(Ren'Py 8.x)
Python 3 では、文字列がデフォルトで Unicode になった。
# Python 3 — これがもうUnicode
"戦闘BGM.ogg"
u"" プレフィックスは不要になり、すべての文字列リテラルがネイティブ Unicode として扱われる。Ren'Py 8.x は Python 3.12 ベースで動作するため、ファイル名の文字列処理で Python 2 時代のエンコーディング問題が発生しなくなった。
つまり、Ren'Py が日本語ファイル名をサポートしたわけではなく、Python 3 が Unicode をネイティブに扱うようになった結果、自然に通るようになった ということだ。
なぜ危ないのか:配布で壊れる3つのケース
開発マシンで動くのと、プレイヤーの環境で動くのは別の話だ。日本語ファイル名は、配布プロセスで3つの地雷を踏む可能性がある。
ケース1: macOS の Unicode 正規化問題
macOS のファイルシステムは、ファイル名に Unicode 正規化を適用する。旧式の HFS+ はファイル名を NFD(分解形) に変換して保存し、現行の APFS はディスク上の元のバイト列を保持するが、ファイル検索時に正規化を無視した比較を行う。一方、Windows や Linux は通常 NFC(合成形) を使い、バイト単位で完全一致する。
例えば「が」という文字は、内部的に2つの表現がある。
| 形式 | 表現 | 説明 |
|---|---|---|
| NFC | が(1文字) | 合成形。Windows/Linux の標準 |
| NFD | か + ゙(2文字) | 分解形。macOS HFS+ の標準 |
ZIPファイルにNFCで格納された 戦闘BGM.ogg を macOS で展開すると、ファイルシステムの正規化により別のバイト列として扱われる場合がある。Ren'Py がNFCのバイト列で検索すると、正規化後の名前と一致せずファイルが見つからない。
実際に、商用 Ren'Py ゲーム「WORLD END ECONOMiCA」で日本語ファイル名 飛び_右下.png が macOS で読めないという問題が 報告されている。
ケース2: ZIP ファイル名の文字化け
Ren'Py のビルドは ZIP や tar.bz2 で配布ファイルを生成する。ZIP 形式には ファイル名のエンコーディング標準がない。
Python 3 の zipfile モジュールは UTF-8 フラグ(ビット11)を設定して格納するが、古い解凍ツールや Windows エクスプローラーの一部バージョンはこのフラグを無視する。結果として、日本語ファイル名が文字化けしてゲームが起動しない。
ケース3: Web / Android ビルドの未検証
Ren'Py は Web ブラウザ向けビルド(Emscripten / WebAssembly)と Android APK ビルドをサポートしている。しかし、これらのプラットフォームで日本語ファイル名が正しく動作するという公式の確認はない。Web ビルドでは HTTP の URL エンコーディングとの相互作用も懸念される。
安全な代替:ASCIIファイル名 + エイリアス
ファイル名は ASCII で統一し、スクリプト上の可読性は define エイリアスで確保するのが最も安全だ。
音声ファイル
# audio/ ディレクトリのファイル名は ASCII
# audio/battle_bgm.ogg
# audio/village_theme.ogg
# audio/rain_ambient.ogg
define audio.battle_bgm = "audio/battle_bgm.ogg"
define audio.village_theme = "audio/village_theme.ogg"
define audio.rain_ambient = "audio/rain_ambient.ogg"
label start:
play music battle_bgm
play sound rain_ambient
define で audio 名前空間にエイリアスを作ると、play music 文でファイルパスを書く必要がなくなる。変数名を見れば何の音声かわかるので、可読性も問題ない。
画像ファイル
Ren'Py の画像自動検出は、ファイル名のスペース区切りを画像名にマッピングする(画像表示の公式ドキュメント)。
images/
├── bg forest.png → scene bg forest
├── bg castle.png → scene bg castle
├── eileen happy.png → show eileen happy
└── eileen sad.png → show eileen sad
手動で定義する場合も ASCII で統一する。
image bg forest = "images/bg_forest.png"
image bg castle = "images/bg_castle.png"
命名規約
プロジェクト全体で以下のルールを決めておくと、ファイルが増えても管理しやすい。
# 音声
audio/{種類}_{説明}.ogg
audio/bgm_battle.ogg
audio/sfx_sword_slash.ogg
audio/amb_rain.ogg
# 背景
images/bg {場所}.png
images/bg forest.png
images/bg castle.png
# キャラクター
images/{名前} {表情}.png
images/eileen happy.png
images/eileen angry.png
FAQ
中国語や韓国語のファイル名は使える?
日本語と同じルールが適用される。開発環境では動くが、配布時のリスクも同じだ。macOSの正規化はアクセント付きラテン文字(é、ñ、ü)にも影響するので、非ASCIIファイル名はすべて避けたほうがいい。
Ren'Py 7.x では日本語ファイル名は使える?
部分的にしか使えない。Ren'Py 7.x は Python 2 ベースで、文字列はデフォルトでバイト列だ。音声ファイルの UnicodeEncodeError は 2014年に修正 されたが、Python 2 の Unicode サポート自体が限定的なため、8.x よりもリスクが高い。
Ren'Py が将来 Unicode ファイル名を公式サポートする可能性は?
現時点でその兆候はない。PyTom は Lemma Soft Forums で一貫してASCIIファイル名を推奨しており、公式ドキュメント にもUnicodeファイル名のサポートに関する記述はない。クロスプラットフォームの正規化問題を解決する必要があるため、公式サポートは難しいだろう。
ディレクトリ名に日本語を使っても同じ問題が起きる?
はい。ディレクトリ名もファイル名と同じファイルシステム操作を通る。images/キャラクター/eileen happy.png のようなパスでは、ディレクトリ名もファイル名も正規化やエンコーディングの影響を受ける。
ラベル名や変数名に日本語は使える?
Python 3 は Unicode 識別子を許可 しているので、label 戦闘シーン: は技術的には動く。ただし、Ren'Py のスクリプトパーサーがすべての Unicode 識別子を一貫して処理する保証はなく、日本語を読めない協力者との共同作業も難しくなる。コードの識別子はASCIIにしておこう。
既存の日本語ファイル名をASCIIに一括変更するには?
ファイルマネージャーやバッチリネームツールでファイル名を変更し、.rpy スクリプト内の参照をすべて更新する。プロジェクト全体で旧ファイル名を検索すると漏れを防げる。変更後に define エイリアスを導入すれば、将来の参照変更はエイリアス定義の1行だけで済む。
macOS の正規化問題は APFS でも起きる?
起きる。HFS+ はファイル名をNFDに強制変換していた。APFS はディスク上の元のバイト列を保持するが、ファイル検索時に正規化を無視した比較を行う。結果として、NFCで書かれたファイル名がバイト完全一致を期待する検索で見つからない、という実害は同じだ。
まとめ
- 動くか? — Ren'Py 8.5.2 では日本語ファイル名は動作する
- なぜ? — Python 3 のネイティブ Unicode 処理 のおかげ。Ren'Py の公式機能ではない
- リスク — macOS 正規化、ZIPの文字化け、Web/Android未検証。配布後に壊れる可能性がある
- 推奨 — ASCII ファイル名 +
defineエイリアスが安全で実用的
Ren'Py の基本については 入門ガイド を、音声設定の詳細は オーディオガイド を参照してほしい。
公式リソース:
- Ren'Py公式ドキュメント — 全機能のリファレンス
- 画像の表示 — 画像の自動検出と命名規則
- Audio — 音声再生の公式リファレンス
- Python 3 Unicode HOWTO — Python の文字列モデルの詳細
- Apple APFSドキュメント — APFS の正規化動作
- r/RenPy — コミュニティ
関連記事: