コンテンツにスキップ

里々 Unicode 版(Mc202-1)公開

里々 Unicode 版(Mc202-1)公開。赤いポストと狛犬のイラスト

内部を Unicode にした里々を、Mc202-1 から正式版として公開します。

目標は一貫して互換性でした。20 年以上使われてきた辞書・セーブデータ・SAORI との組み合わせを、satori.dll の差し替えだけで引き続き使えることを最優先にしています。そのうえで、絵文字や UTF-8 の辞書が書けるようになり、長年の不具合も直り、喋りの組み立てが大きく高速化しました。

このページは、ゴースト作者向けに、従来の版(Mc1XX)から何が実質的に変わるのかをまとめたものです。

結論:satori.dll を置き換えるだけです

  • 辞書は書き直す必要がありません。 Shift_JIS の辞書はそのまま読めます。UTF-8 の辞書も読めますが(自動判定)、変換は不要です。
  • セーブデータはそのまま引き継がれます。 Shift_JIS の従来のセーブデータも、暗号化セーブ(.sat)も読み込めます。
  • 外部の SAORI も、ssu も、これまでどおり呼べます。
  • 実際に開発チームの側でも、ほとんどの場合は何も考えずに置き換えています。

気にするのは、次の 1 点です。置き換える前に読んでください。

導入前に:元の版(Mc1XX)には上書きだけでは戻せません

この版で一度起動すると、セーブデータは UTF-8 で保存されます。従来の版(Mc172-3 など)は UTF-8 のセーブデータを正しく読めないため、satori.dll を元の版に差し替えただけでは、変数が化けたり失われたりします。UTF-8 で書いた辞書も、従来の版では読めません。

置き換える前に、セーブデータ(satori_savedata.txt と satori_savebackup.txt。暗号化していれば .sat)と、ゴースト全体のバックアップを取ってください。 戻す方法はもとに戻したくなったらにあります。

バージョンは (里々のバージョン) で確認できます(phase Mc202-1 のように、入れた版の番号が出ます)。

速くなりました

辞書の書き方を変えなくても、置き換えるだけで速くなります。トークの組み立てで毎回通る処理を、根本から見直した成果です。

実際のゴーストで:全体で約 12 倍

里々の辞書を大規模に使うゴースト LilyNovelPlayer を、SSP の動きをまねるテスト用ドライバで、起動からチュートリアル・セーブ/ロード・コンフィグ・ギャラリーなどを経て終了まで、200 リクエスト流して測りました(同じ PC、3 回の平均。Mc201-5 の時点の値)。

従来の版(Mc172-3) Unicode 版 速さ
読み込み 503ms 140ms 約 3.6 倍
OnBoot 577ms 95ms 約 6.1 倍
200 リクエストの合計 8,841ms 744ms 約 12 倍

起動(読み込み+OnBoot)では約 4.6 倍です。同じ辞書が同じ応答のまま速く動きます。応答(このときは自動ウェイト \_w[n] の値を除く)と、終了時のセーブデータ(起動時間の累計を除く)は、従来の版と完全に一致していました。

処理ごとの内訳:7〜25 倍

1 リクエストあたりの処理時間です(同じ辞書を、同じ環境で計測。Mc201-3 の時点の値)。従来の版(Mc172-3)と比べて、おおむね 7〜25 倍の速さです。

内容 従来の版(Mc172-3) Unicode 版 速さ
カッコの入れ子(約 600 回の呼び出し) 5.68ms 0.84ms 約 6.8 倍
300 語の単語群から 100 回選ぶ 4.11ms 0.32ms 約 12.8 倍
3000 語の単語群から 100 回選ぶ 28.5ms 1.12ms 約 25 倍
2 万字のトーク 38.0ms 2.25ms 約 17 倍

何が速くなったのか:

  • 単語群・文の選択:従来は選ぶたびに、重複回避のための候補を全要素から作り直していたため、群が大きいほど時間が伸びていました。今は、条件式のない群では要素が変わらないかぎり作り直しません。語数の多い辞書ほど効果が出ます。
  • 長いトークの変換と () の展開:1 文字ずつ処理するたびに無駄なメモリ確保をしていたのと、文字列を少しずつ伸ばすたびに確保し直していたのを取り除きました。長いトークほど文字数の割合以上に遅くなる問題もなくなっています。
  • 余計な実行がなくなりました:結果を使わないのに、内蔵関数・SAORI の引数を二重に展開していた処理を削っています。速くなるだけでなく、引数に (…) が文字として入っていたときの余計な実行(単語の選択や set などの副作用)も起きなくなります。
  • ssu の reverse:20 万文字の文字列で数十秒止まっていたのを直しました。

数字は目安です。環境や、辞書・トークの内容によって効果は変わります。細かい一覧はACP 版との違いにあります。

作者が気にする違い

文字を「バイト」で扱うか「文字」で扱うかの違いと、長年の不具合を直したことによる違いです。該当する書き方をしているときだけ確認してください。

文字数・バイト数に関わるもの

書き方 従来の版(Mc1XX) Unicode 版(Mc2XX)
自動挿入ウェイト バイト数で数える(全角 1 文字が 2) 半角換算で数える(全角 1 文字が 2、半角 1 文字が 1)。従来の版と同じ長さ(Mc202-1以降)
(バイト値、n) 1 バイトの文字を返す n を Unicode のコードポイントとして 1 文字を返す
calc での文字列の長さ比較 バイト数 文字数
sprintf の %s の幅 バイト数 半角換算(全角は 2)で数える
$括弧展開サイズ制限 バイト数 文字数(実質約 2 倍まで展開できる)
コミュニケートの点数 バイト数に基づく 文字数に基づく(一致した語が全角のみなら同じ点数)

通信・文字コードに関わるもの

書き方 従来の版(Mc1XX) Unicode 版(Mc2XX)
セーブデータ Shift_JIS 常に UTF-8 で保存(読み込みは自動判定)
ベースウェアとの通信 Shift_JIS リクエストの Charset に従う(SSP とは UTF-8)
SAORI・SSTP・ssu との通信 ACP UTF-8
UTF-8 の辞書の記号 (読めない) 波ダッシュ(〜 U+301C)と全角チルダ(~ U+FF5E)などを別の文字として扱う。里々は両方を受け付ける(文字コード)

SAORI は、里々が送る Charset ヘッダに従って動くものなら問題ありません。常に Shift_JIS で解釈してしまう古い SAORI だけ、文字化けすることがあります。その場合は SAORI 側の更新をご確認ください(SAORI の通信)。

直った不具合の分、結果が変わるもの

従来の版の挙動に頼った書き方をしていると、結果が変わります。書いたとおりに動くようになった、という方向の変更です。

書き方 従来の版(Mc1XX) Unicode 版(Mc2XX)
式の ^ ビット XOR べき乗
式の =~ !~ 常に 0 部分文字列の判定
計算の数値 32 ビット(2147483647 を超えるとあふれる) 64 ビット
(time_t) 2038 年以降に負の数になる 正しい値を返す
ssu の sprintf %i が 8 進、%.3s の精度が無効 %i は 10 進、%.3s が効く
(直前の選択肢名) 常に空 選ばれた選択肢の ID
ssu の mkdir と lsimg 外部からのイベントでも実行できた SecurityLevel: local のときだけ実行する

新しくできた上限

暴走を止めるための上限が加わりました。ふつうの辞書では届きません。

  • $呼び出し総数制限(既定 100000):呼び出しと繰り返しの合計回数の上限です。超えるとログに 呼び出し総数超過 と出ます。意図して巨大な繰り返しを書いているなら、この値を上げてください。
  • 括弧の入れ子は 1000 段まで、calc の式のカッコは 200 段までです。
  • 辞書の本文には、内部の特殊表現に使う Unicode の私用領域の文字(U+E0FF ほか)を含めないでください。

互換性をどう確かめたか

次の項目を確認したうえで、正式版にしています。

  • 従来の版と Unicode 版の satori.dll に、同じ Shift_JIS の辞書とリクエストを与えて、応答を比較した(直した不具合の分を除いて一致)
  • 里々 Wiki の記述例のうち複雑そうなものを集めて、通ることを確かめた(スモークテスト)
  • SSP で実際にゴーストを起動して、SSTP でイベントを送り、UTF-8 で通信できること、絵文字入りのコミュニケートに応答できることを確かめた
  • 外部の SAORI(2 種類)を UTF-8 で呼べることを確かめた
  • セーブデータの保存と再読み込み(Shift_JIS の旧セーブの読み込み、UTF-8 での保存、暗号化 .sat)を確かめた
  • このマニュアルを書くために、ssu の全関数と () 内蔵関数、システム変数の大半を実機で動かした

世の中にある多様なゴーストや SAORI との組み合わせは、すべては確かめきれていません。Windows 以外のビルド(POSIX・Emscripten)は、構文チェックまでです。気づいた違いは、次の窓口へ教えてください。

使えるようになったもの

互換性を保ったまま、できることが増えています。使うかどうかは自由です。一覧はACP 版との違いにあります。

直った不具合

異常終了・無限ループ・止まる問題や、書いたとおりに動かなかったものを多数直しています。使い手に関わる順にまとめたものが、直された不具合です。

不具合を見つけたら

従来の版と違う結果になったもの、エラーになるようになったもの、仕様書と実際の動きが食い違うものがあれば、教えてください。GitHub のアカウントがなくても大丈夫です。

次のような内容を書いていただけると、原因を追いやすくなります。「なんとなくおかしい」だけでも構いません。

■ バージョン
(里々のバージョン)の結果: phase Mc202-1(実際に出た値)
OS: Windows 11
ベースウェア: SSP 2.x.x
ゴースト: (名前。配布されているもの・自作・その他)

■ 起きたこと
(例)選択肢を選んだあと、従来の版と違う文が選ばれるようになった

■ 従来の版ではどうだったか
(例)Mc172-3 では、この文は \_w[24] だった

■ 再現の手がかり
(例)dic_talk.txt のこの文で起きる(辞書の該当部分)
(可能なら)ShioriEcho での結果、ログ(れしば・tama)の内容

再現の確認には、次の方法が使えます。

  • ShioriEcho: satori_conf.txt の *初期化 に $デバッグ=有効 と書くと、里々の文を 1 行ずつ展開して結果を返せます(ShioriEcho とデバッグ)
  • ハーネス: satori.dll を SSP なしで直接呼ぶ小さなプログラムが、リポジトリの satoriya/test/harness にあります
  • tama: 辞書のエラーは、ログ受信ツール tama で確認できます

もとに戻したくなったら

バックアップから戻す(確実な方法)

  1. ゴーストを終了する。
  2. satori.dll を、バックアップした従来の版に戻す。
  3. satori_savedata.txt と satori_savebackup.txt を、バックアップから戻す。

3 を忘れて従来の版で起動すると、UTF-8 のセーブデータが読めずに、変数が失われます。

バックアップがないとき:セーブデータを Shift_JIS にする

セーブデータ(satori_savedata.txt と satori_savebackup.txt)は、中身の書式は従来の版と同じで、文字コードが UTF-8 になっているだけです。ゴーストを終了したあと、この 2 つをテキストエディタで開き、文字コードを Shift_JIS(ANSI、CP932)にして保存し直すと、従来の版でも読めるようになります。

  • 改行は CRLF のままにしてください。
  • Shift_JIS にない文字(絵文字や「髙」など)が変数の値に含まれていると、変換で ? になったり、失われたりします。その変数は、戻したあとの値がずれます。
  • 暗号化セーブ(.sat)はエディタで開けないので、この方法は使えません。
  • UTF-8 で書いた辞書も、同じように Shift_JIS にする必要があります(Shift_JIS にない文字を使っていない場合のみ)。
  • 変換前に、必ず現在のファイルのコピーを取ってください。

関連