弟のトモコレを見ていたらだいぶ面白かったので、動的に名前を呼んでもらう方法はないかなあとやってみました。
(もうとっくにどなたかがやっている気がしますが、まあ、思い付きの検証として。)
合成音声エンジンは COEIROINK を使いました。ローカルで動くので、起動さえしておけばネットが切れていてもしゃべります。ノベルゲームエンジンの Ren'Py 8 から HTTP POST で叩いて WAV を受け取り、その場で voice() に流す仕組みです。
必要なもの
- Ren'Py 8系(Python 3で動くやつ)
- COEIROINK(ローカル日本語TTS。起動して API を待たせておく)
外部APIを叩かないので、ネットが切れていても動く。ここ重要。
流れ
プレイヤーが名前入力
↓
Ren'Py が台詞を組み立てる
↓
http://127.0.0.1:50032/v1/synthesis にPOST
↓
WAVが返ってくる → game/generated_voice/ に保存
↓
Ren'Py の voice() で再生
面白いところは、プレイヤーが自由に入力したセリフも読み上げてくれるところです。
キャラに voice_tag を持たせる
define guide = Character("案内役", color="#8fd3ff", voice_tag="guide")
voice("...", tag="guide") で鳴らしておけば、別キャラの発話が割り込んでも案内役の音声だけ独立して止めたり差し替えたりできそうです。
落ちないようにする
発表中や配信中に黒画面で固まるのが一番怖いので、COEIROINK が起動していないときは例外を捕まえて画面にエラー文字列を出して進めるようにしてあります。
$ voice_file = None
$ voice_error = None
python:
try:
voice_file = synthesize_dynamic_voice(dynamic_line, label=player_name)
except Exception as exc:
voice_error = str(exc)
留意点
読み間違い
TTSは漢字の読みを自前で推定するので、珍しい名前や当て字は読み間違えてしまいます。入力をひらがな/カタカナでも受けられるようにしておくのがよさそうですね。
レイテンシ
初回レイテンシは 1〜3秒。即レス感はありません。
上手いことやるのだったら音声の再生直前ではなく、どっかで生成しておくと良いですね。
キャッシュ
キャッシュが膨らみそうですね。
ローカル前提
プレイヤー側で COEIROINK を立ち上げる必要があるので、ブラウザ配布や即起動には向きません。
また、配布するなら話者のライセンスの確認が要りますね。話者ごとに利用条件が違うので、ゲームに音声を載せて配布するときは要チェックです。
今だとほかにオープンライセンスのTTSがありそうなので、探してみると良いと思います。
ちなみに VOICEVOX でも
VOICEVOX もローカルサーバーを立てて同じノリで叩けるので、リアルタイムで喋るずんだもんとかも普通に行けるんちゃうかと思います。エンドポイントの形が違うだけで、考え方は丸ごと流用できます。
余談:複数ファイルのダウンロードに Claude
複数ファイルのダウンロードは非常にしんどいのですが、Chrome の Claude 拡張機能でうまくいきました。今回使った COEIROINK の GPU 版は分割ダウンロードでファイルがいくつかに分かれていて、人力でぽちぽち落とすとげんなりするやつなのですが、まるっと巻き取ってくれます。

ほかに役に立ったのが、確定申告のための領収書を一気にごとっと集めてきてもらうところ。便利でした。(一括で確定申告とかはさせてませんが)。
それから DLsite でデカめのゲームをダウンロードするとき分割ダウンロードになることがあると思いますが、あれもやってくれるので便利です。
ルンバの如く掃除して環境を整備してからあら~上手だね~みたいなことはよくやってますがなんかそれはずるい気がするので、人間がやらせたくないことをやらせるのに向いています。