MERMAID LAB

原稿フォーマット仕様

novel-src/episodes/*.txt の書き方。npm run build:novel で自動変換される。

01ゴール

執筆者が、以下のフォーマットに沿ったテキストファイルを用意し、決められた1つの操作(コマンド実行など)を行うと、下記の解釈ルールに従って自動的にサイトの小説ページへ反映される仕組みを実装すること。

例えば、執筆者が以下のようなテキストを用意した場合、

私は闇の中で、キャラAの声を聞いた。
▼
>「大丈夫、ここにいるから」
▼
キャラAはそう囁いた。

サイト上では「▼で区切られたブロックごとに、タップで1つずつ表示が進む」「>で始まる行はセリフとして左に線が入った見た目で表示される」という形に、自動的に解釈・反映される。

以下、詳細な解釈ルールを記載する。

02基本ルール

Episode 3
「微睡の人魚、シノ」

私は闇の中で、キャラAの声を聞いた。
▼
>「大丈夫、ここにいるから」
▼
キャラAはそう囁いた。

03挿絵

以下のように書かれている箇所は、挿絵を挟む位置を示す。

《挿絵:scene03_01.png》

ファイル名だけを書けばよい(パスは不要)。画像自体はpublic/img/web-novel/直下に置く。例えば《挿絵:scene03_01.png》と書いた場合、public/img/web-novel/scene03_01.pngを用意する(サイト上では自動的に/img/web-novel/scene03_01.pngとして読み込まれる)。まだ画像が無い場合は「[挿絵]」というプレースホルダー表示になる。

04選択肢(軽いもの・演出用)

話しかけられた!
▼
===選択===
殴る
好物を渡す
===

【殴る】
私はキャラAを殴った。
▼
>「いってー! なにすんだよ」
▼
キャラAは怒った声をあげた。
▼
《好感度:キャラA-1》
▼
【殴る:終了】

【好物を渡す】
私はキャラAに好物を差し出した。
▼
>「え、くれんの? ラッキー」
▼
キャラAは嬉しそうに受け取った。
▼
《好感度:キャラA+1》
▼
【好物を渡す:終了】

(ここから下は、どちらを選んでも共通)
二人はそのまま歩き出した。

構文ルール

05重要な選択肢(キャラクターの生死に関わるもの)

===重要選択===と書かれている場合、対象は敵・味方を問わず誰かの生死が決まる場面であり、通常の選択肢とは別のUI(長押し確定)で扱う。

===重要選択===
キャラAを助ける
キャラAを見捨てる
===

【キャラAを助ける】
(本文)
【キャラAを助ける:終了】

【キャラAを見捨てる】
(本文)
《状態:キャラA=死亡》
【キャラAを見捨てる:終了】

構文は===選択===と同一。===重要選択===である場合のみ、通常のタップではなく長押し確定のUIとして扱う。

《状態:キャラ名=値》 は、《好感度:キャラ名+1》と同じくブロック内の任意の位置に置かれる、そのキャラクターの状態を記録するマーカーである。値は執筆者が自由に決めてよい(例:死亡、離脱、復帰)。同一キャラクターに対して複数回このマーカーが置かれた場合、最も後に書かれたものが最新の状態として上書きされる(例:「離脱」の後に「復帰」と書けば、以降は「復帰」状態として扱われる)。この記録は、Episode12のエンディング分岐の条件リストから参照される。

06アイテムの取得・喪失

《アイテム:回復薬=取得》
《アイテム:回復薬=喪失》

《アイテム:アイテム名=取得》 / 《アイテム:アイテム名=喪失》 は、ブロック内の任意の位置に置かれる、アイテムの所持状態を記録するマーカーである。使用による消費も「喪失」として扱う。《状態:キャラ名=値》と同様、最も後に書かれたものが最新の所持状態として上書きされる。この記録は、Episode12のエンディング分岐の条件リストから参照される。

画面に表示される文言を、記録される値とは別に指定したい場合は、|の後に表示文言を書く。

《アイテム:カードキー=喪失|カードキーを使用した》

この場合、記録される値は喪失のまま(条件分岐などから通常通り参照される)だが、画面には「カードキーを使用した」という文言が表示される。|が無い場合は、これまで通りの標準表示(例:「アイテム「カードキー」を喪失した」)になる。

07条件分岐(アイテム所持などによる場面の解放)

アイテムの所持状況などに応じて、読者に選ばせるのではなく、システム側が自動で判定してルートを振り分ける場面を、以下のように書く。

===条件===
《アイテム:カードキー=取得》
===

【はい】
私はカードキーを使って扉を開けた。
▼
《アイテム:カードキー=喪失|カードキーを使用した》
▼
>「よく来たね」
▼
===選択===
話を聞く
すぐに立ち去る
===

【話を聞く】
(本文)
▼
《好感度:キャラA+1》
【話を聞く:終了】

【すぐに立ち去る】
(本文)
▼
《好感度:キャラA-1》
【すぐに立ち去る:終了】

【はい:終了】

【いいえ】
扉には鍵がかかっていて、開かなかった。
【いいえ:終了】

(ここから下は、どちらのルートでも共通)
私は先へ進んだ。

構文ルール

08Episode12(最終話)のエンディング分岐

エンディングは固定の計算式ではなく、それまでの物語で本文中の《状態:キャラ名=値》・《好感度:キャラ名±1》・《アイテム:アイテム名=取得/喪失》によって積み重なったフラグを、優先順位付きの条件リストとして上から順に照合し、最初に合致したものに決定する。

1. キャラAの状態が「死亡」 → 特定キャラA喪失エンド
2. キャラBの状態が「離脱」 → 特定キャラB不在エンド
3. (条件は随時追加される)
最後. どれにも当てはまらなければ → デフォルトエンド

09実装要件:更新操作の単純さ

原稿テキストファイルからサイトへの反映は、AIの都度の介在を必要としない、決まったコマンド1つで完結する仕組みとすること(変換処理+公開までを自動化する)。

実装済み: npm run build:novel がこの変換を行う。公開(firebase deploy)は別コマンドとして手動実行する運用になっている。

← 管理画面TOPに戻る