14. サンプルゲーム『灯送りの夜』

1.0.4 から、最初から最後まで遊べる短編のノベルゲームが入っています。 スタートからエンディング、エピローグまで、選択肢・フラグ・複数の結末がそろった形を、シナリオを読みながら確かめられます。

まず遊んでみましょう。
配布物の SampleGame\lumina.exe を起動します(1 周 15〜20 分くらい)。 説明は SampleGame\はじめにお読みください.txt 、変数の一覧と分岐図は SampleGame\フラグと分岐.txt にあります。

14.1 ばらのファイルで置いてある理由

このサンプルは、作品を作るときの参考にするためのものです。シナリオ( .txt )も絵も音も、パック( .laf )にせず、そのままフォルダに置いてあります。 lumina.exe は自分の隣の GameData を読むので、NovelAuthor の「新規作成」で作ったフォルダと同じ並びです。

14.2 シナリオの分け方

ファイル( GameData\data0\scenario ) 中身 見てほしい書き方
nv_prologue.txt 序章 変数の初期化・選択肢・ファイルをまたぐ jump
nv_ch1.txt 第一章 イベント CG・シーン鑑賞・ gosub ・選択肢の中の選択肢
nv_ch2.txt 第二章 回数を数えるくり返し・行った場所を選択肢から消す
nv_ch3.txt 第三章 印で変わる会話・演出の組み合わせ・全画面の文章
nv_ch4.txt 第四章 印の組み合わせで分ける・周回で増える選択肢
nv_end_*.txt 結末 4 本 ベース+差分の CG・入口が複数ある結末
nv_epilogue.txt エピローグ 結末ごとの書き分け・周回の記録・エンドロール

分岐は「印を残して合流する」形にしてあります。選択のたびに話を分けたままにすると、シナリオの量がすぐに増えるためです。

シーン鑑賞の曲: シーン鑑賞は *scene_ID のラベルから始まるので、ラベルより前の bgm ・ seloop は通りません。範囲の前から鳴らしている曲は、鑑賞のときだけ通る行で鳴らします( nv_ch1.txt の *scene_nv_pier )。ふつうに遊ぶときは jump でその行を飛ばすと、鳴っている曲が頭に戻りません。 seloop は scene_end の前に stopse で止めます。

14.3 周回の記録の受け渡し

setsysflag で書いた値はどのセーブにも共通で残りますが、シナリオの if からは読めません。このサンプルでは次の形で受け渡しています。

  1. エピローグが setsysflag nv_end_1 1 のように書く
  2. 次の周回の序章が sysscript NvRecord を呼ぶ( System.getSystemFlag で読み、 GameState.set で入れる)
  3. 序章が gs_get nv_seen_all nv_seen_all でシナリオの変数へ受け取る

タイトルでは同じ値を System.getSystemFlag で読み、見た結末の数だけ灯を出しています( system/title_enhanced.txt )。

14.4 直して試す

SampleGame を丸ごとコピーして、コピーの .txt を直し、 lumina.exe を起動し直します。開発中は .txt で動くので、すぐ結果を見られます。 .lsf は配布のときに使う物で、 Tools\ScriptEncryptor で作り直します。

NovelAuthor で 灯送りの夜.lnp を開くと、フローチャートで全体を見ながら編集できます。

14.5 デバッグモードで動かす

このサンプルには GameData\data0\system\DevMode.txt があるので、起動するだけでデバッグモードになります。窓の題に [Debug Mode | FPS] が出て、窓のメニューに「デバッグ」が増えます。

変数の値を確かめるとき: 「デバッグ」→「デバッグツール」→「フラグインスペクタ」( Shift+F3 )に、変数の名前と今の値の一覧が出ます。 setvar ・ addvar の変数( nv_nagi など)は ScenarioFlag のタブ、 setsysflag などの共通の値は SystemFlag のタブに sysflag.名前 の形で出ます。窓を開いている間はシナリオの命令が進むたびに更新され、変わった物に ★ が付きます。変わった順は履歴のタブで見られます(窓を閉じている間の変化は履歴に入りません)。値は窓から書き換えられます。スクリプトデバッガの Variables のタブにも同じ値がまとめて出ます。 gs_set ・ gs_add の値(GameState)は GameState のタブに出て、ミニゲームの実行中も更新されます(文字の値は "" で囲んで出ます。Variables には gs.名前 の形で整数だけが出ます)。

配布するとき: DevMode.txt はプレイヤーに渡す物に入れません。入っていると、プレイヤーの画面にデバッグのメニューが出て、ログのファイルもできます。ReleaseBuilder でリリース版を作ると自動で外れます。手で配るときは自分で外してください。

自分の作品では
GameData\.author の鍵は全員が持っている「見本の鍵」です。自分の作品は NovelAuthor の「新規作成」で作り、鍵も作品ごとのものを使ってください。

14.6 タイトルをムービーのように動かす

タイトルは動画を流しているのではありません。止まった背景の上に、透明の地に「光だけ」「霧だけ」を描いた絵を何枚も重ね、それぞれをゆっくり動かしています。書いてある場所は system/NvTitleFilm.txt (短いファイルです)。

Title.addImage("nvt.mist", "data1/title/nvt_mist_far", -360, 350, 2000, 210, "back");
Title.setImageMotion("nvt.mist", 300, 6, 140000, 26, 50, 37000, 0, 0, 2500);
Title.setImageMotion の引数 意味
id Title.addImage で置いた名前
揺れ横・揺れ縦・揺れ ms 揺れの幅と 1 周の時間。横は sin、縦は cos で楕円を描く。時間が 0 なら揺らさない
濃さ下・濃さ上・明滅 ms 0〜100 の濃さと、下と上を行き来する時間。時間が 0 なら濃さ上のまま
ずれ ms(省略可) 時刻のずれ。同じ周期の絵がそろって動かないようにする
加算(省略可) 1 で加算合成(光の絵)、0 で通常の合成(霧・雲)
出る ms(省略可) いまからこの時間で濃くなる。0 ですぐ

14.7 エンドロールをムービーのように流す

後ろの映像は system/NvRollFilm.txt 、文字と飛ばす操作は今までの StaffRoll ( system/StaffRoll.txt )です。動画のファイルは使っていません。

  1. FX.beginBatch() の中で、場面も灯も全部「何ミリ秒後に出て、どう動いて、いつ消えるか」を予約する
  2. 曲を鳴らす
  3. FX.endBatch() で映像の 0 秒を決め、すぐ StaffRoll.run() で文字を流す
  4. 途中で飛ばされたら、黒い絵を FX.image で重ねて暗くし、 FX.clearAll() で片付ける
FX.image("nvf.lake", "data2/nv_lake", 0, 0, 1280, 720);
FX.anim("nvf.lake", 3000, 11100, 900, 3, 0);                    // 出る ms, 保つ ms, 消える ms, 緩急, 待つ ms
FX.transform("nvf.lake", 1.0, 1.08, 0, -14, 15000, 0, 0);       // 拡大元, 拡大先, 動く横, 動く縦, 動く ms, 緩急, 待つ ms
FX.setSmooth("nvf.lake", 1);                                    // ゆっくりの動きが段付きに見えないようにする

素材はすべて Tool\01_Development\gen_novelsample_art.py の計算で作りました( --only film )。自分の作品では、霧や光の絵を差し替えるだけで同じ動きを使えます。