第6章 仕様
ファイル形式・セーブ・フォルダマッピングなどの仕様です。作成手順は 制作者向け入門、配布手順は 第3章 を参照してください。
6.1 実行ファイル仕様
| 項目 | 値 |
|---|---|
| 実行ファイル(ビルド出力) | Windows: lumina.exe / ブラウザ: lumina.html + lumina.js + lumina.wasm / Android: lumina.apk(Play 向け: lumina.aab) |
| 対応プラットフォーム | 起動可: Windows / Steam / ブラウザ / Android(完全互換ではない)。開発中: Linux / iOS / PlayStation系 / Switch系 |
| Android | 最小 API レベル 24。ABI は arm64-v8a(実機)と x86_64(PC のエミュレータ) |
| 描画 API | Windows: DirectX 12 / ブラウザ: WebGPU(Dawn) / Android: OpenGL ES 3.0(Vulkan / Metal はスケルトン) |
| 音声 API | Windows: LUMINA Audio(XAudio2 / WASAPI) / Android: OpenSL ES / ブラウザ: Web Audio |
| 動画 | Windows: lmmovie(DirectShow / Media Foundation / Theora)/ Android: MediaCodec / ブラウザ: HTML <video> |
| スクリプトエンジン | lumina_scriptengine(SimpleScript と LUMINA Script の 2 つの書き方)。SystemScriptEngine(起動・UI)と ScenarioScriptEngine(本編)の 2 系統 |
6.1.1 プラットフォーム別バックエンド・成熟度
同じシナリオ・素材・データ構造を共有しますが、描画/音声/プラグインの実装はプラットフォームごとに異なります。現在の状況は次の通りです。
| プラットフォーム | 描画 | 音声 | 動画 | プラグイン | 状況 |
|---|---|---|---|---|---|
| Windows | DirectX 12 | LUMINA Audio / XAudio2 / WASAPI | lmmovie(DS/MF/Theora) | DLL(DLL\ フォルダ) | 起動可(主要ターゲット) |
| Steam | (Windows と同じ) | (Windows と同じ) | (Windows と同じ) | mrusteam(既定の許可一覧に入っていて、使うときに自動で読み込む) | 起動可 |
| ブラウザ(WASM) | WebGPU(Dawn) | Web Audio | HTML <video> | DLL は使わない。アニメ・モーションは本体に内蔵 | 起動可 |
| Android | OpenGL ES 3.0 | OpenSL ES | MediaCodec | DLL は使わない。アニメ・モーション・音声デコーダ(OGG Vorbis / Opus)は本体に内蔵 | 起動可 |
| Linux | 雛形 | 雛形 | — | — | 開発中(起動不可) |
| iOS | 雛形 | 雛形 | — | — | 開発中(起動不可) |
| PlayStation系 | — | — | — | — | 開発中(起動不可・SDK 前提) |
| Switch系 | — | — | — | — | 開発中(起動不可・SDK 前提) |
- WebGPU に対応していないブラウザ … 対応ブラウザ(パソコンの Chrome / Edge、Android の Chrome など)を案内
- https(または localhost)以外で開いている … WebGPU は安全な接続のページでしか使えないため、https での配信を案内(配布サーバーは必ず https にする)
- GPU を借りられない(ハードウェア アクセラレーションが切・対象外の GPU)… 設定の見直しか別のブラウザ・端末を案内
lumina/app/web/shell.html にあります。6.1.2 3D
- Scene3D: glTF / GLB モデルの表示、3D アクション(歩く・撃つ・拾う・調べる)、地形、物理演算(剛体・拘束・ラグドール)。エンジン本体の機能で、別の DLL は要りません。Android / ブラウザでも
Scene3Dの API 128 個のうち 127 個が使え、同じスクリプトがそのまま動きます(残る 1 つは、デバイスの作り直しを知らせるtakeDeviceLost()で、常に 0 を返します)。Android / ブラウザでは画面を触って操作します
API は 第9章 の Scene3D を参照してください。
images/06_specification.png
図6-1: 実行ファイル(プラットフォーム別)
images/06_specification.png6.2 設定ファイル仕様
config.ini
既定では使いません。見本の Config.txt は System.setIniEnabled(false) と System.setIniAutoCreate(false) を指定しており、この状態ではエンジンは config.ini を読まず、書かず、作りもしません(設定は systemdata.dat に保存されます)。
INI と自動作成を両方有効にした場合だけ、exe のフォルダに次の雛形が作られます(Windows)。
# ADV設定
[Window]
Title=ADV Game Engine
Width=1280
Height=720
TopMost=0
FPS=60
WindowResizable=1
AspectRatioLock=2
SingleInstance=1
SingleInstanceKey=ADV Game Engine
[Display]
# ScreenMode: FALSE=ウィンドウ, DirectX12/Win32=仮想フルスクリーン
ScreenMode=FALSE
# WindowMode: Linear=リニア, Cubic=キュービック, Lanczos=ランチョス, SharpLinear=シャープリニア
WindowMode=Linear
CubicStrength=0.80
MultiCore=1
CoreCount=2
ExitDialog=ON
[Confirm]
# DialogType: 0=なし(即実行), 1=Windows(MessageBox), 2=rc(リソースダイアログ), 3=画像ダイアログ
ExitType=3
MenuExitType=3
TitleExitType=1
[Startup]
StartupDialog=OFF
StartupScript=startup.txt
[SystemSave]
# SaveRoot: InstallPath / MyDocuments / AppData / MyGamesDocuments
SaveRoot=InstallPath
SaveDataID=
BrandName=
GameName=
実際の雛形には、ウィンドウアイコンの指定例(IconPath など)のコメントも入ります。[Debug] DebugMode(1 / 0)は INI を有効にしているときだけ読まれ、実行モードを上書きします。INI が無効なら config.ini を置いても無視され、実行モードは system/RunMode.txt(環境変数 LUMINA_RUNMODE → 開発中の印 DevMode.txt → どちらも無ければ Release)で決まります(第3章 3.5)。
systemdata.dat
利用者の設定・既読・システムフラグ等の保存ファイルです。保存先フォルダ(6.8)に作られます。起動ダイアログの表示有無や画面モードなどは、保存した値が Config.txt の既定値より優先されます。
保存形式(System.setSaveDataMode) | 説明 |
|---|---|
""(空文字) | 平文 |
c | AES-GCM で暗号化 |
z | zstd で圧縮(見本の Config.txt はこれ) |
コマンドライン: --systemsave-mode=c / --systemsave-mode=z
6.3 パックファイル仕様(.laf)
| 項目 | 仕様 |
|---|---|
| 拡張子 | .laf。dataN フォルダごとに 1 つ(data0.laf〜) |
| 圧縮 | Zstd(build-pack-data.ps1 の既定はレベル 9。0 は無圧縮)。無圧縮で入れた動画は、Windows ではパックからその場で再生できる |
| 暗号化 | 任意。パスワードを指定したときだけ AES-256-GCM(PBKDF2 で鍵を作り、HMAC で改ざんを検出、ダミーの項目を混ぜる)。暗号化したパックを読むには、エンジンにも同じ語を入れてビルドする(CMake の -DLUMINA_PACK_PASSWORD)。既定のパックは暗号化しない |
| マウント | 起動時に exe のフォルダと 1 階層下(GameData など)の *.laf、および setDataRoot のフォルダの *.laf を自動で読み込む |
| 素のファイルとの関係 | Windows では同じ名前の素のファイルが優先され、パックは見つからないときの予備になる(パックで動かすフォルダには素の dataN フォルダを置かない) |
| ブラウザ | GameData/packlist.json に載ったパックだけを取得する |
| 仮想パス | pack:/// プレフィックス(内部解決) |
| 上限 | 目次(ファイル一覧)の大きさは 256MB まで。範囲がファイルの外を指す項目は読まない |
パックは build-pack-data.ps1(書き出しの dataN をまとめてパック)、luminapack(コマンドライン)、PackTool(GUI)で作れます。どれで作った .laf も全プラットフォーム共通で、実行時に自動で読み込まれます。
6.4 暗号化スクリプト仕様(.lsf)
| 項目 | 仕様 |
|---|---|
| 拡張子 | .lsf |
| マジック | GSCRYPT1 |
| 方式 | AES-256-GCM + HMAC-SHA256、鍵は PBKDF2-SHA256、ダミーの項目を混ぜる |
| 生成ツール | ScriptEncryptor(GUI・コマンドライン) |
| パスワード | 既定のエンジンキー、または Config.txt の System.setScriptPassword と同じ語。Config 自体は既定のエンジンキーで暗号化する(パスワードを設定する前に読まれるため) |
| 対象 | システムスクリプト・シナリオ・マクロ・シミュレーションの設定ファイル |
解決順序(拡張子省略時): System.setExtension で決めた拡張子 → 無ければもう一方(.lsf ⇔ .txt)。.tjs は起動用スクリプトの候補としてだけ探します。
6.5 画像形式仕様(LGC)
| 項目 | 仕様 |
|---|---|
| 形式 | LGC(拡張子 .lgc)。マジック LGC1、16 バイトのヘッダ |
| 圧縮 | ZLIB / ZSTD / LZ4 / LZMA(予測フィルタによる前処理あり) |
| 生成 | LuminaImageCompressor(PNG / JPG / BMP から変換。GUI・コマンドライン) |
| 読み込み | 実行時に自動で読み込み。見本の既定の画像拡張子は lgc |
| 上限 | 縦横とも 16384 ピクセルまで(それを超える画像・大きさ 0 の画像は読まない) |
6.6 フォルダマッピング仕様
System.setFolder(key, path) / System.getFolder(key) で管理します。使えるキーは下の 14 個で、それ以外のキーは黙って無視されます(scenario・macro・system はキーではありません。スクリプトは script の下の system / scenario / macro / lang を見ます)。
| キー | 用途 | 見本の値 |
|---|---|---|
script | スクリプト(配下の system / scenario / macro / lang) | data0 |
ui | UI 画像 | data1 |
bgImage | 背景 | data2 |
eventCg | イベント CG | data3 |
stand | 立ち絵 | data4/stand |
sprite | スプライト | data4/sprite |
bgm / se / voice | BGM / 効果音 / ボイス | data5/sound / data5/se / data6 |
sysse / sysvoice | システム効果音 / システム音声(場面の音とは別の音量) | data5/sysse / data5/sysvoice |
rule | 場面切り替えのルール画像 | data7/rule |
movie | 動画 | data8 |
font | 組み込み書体(指定フォルダの font を見る) | data0 |
6.7 プラグイン仕様
| 項目 | 仕様 |
|---|---|
| 形式 | Windows の DLL。Android / ブラウザは DLL を使わず、同じ機能を本体に内蔵(第8章) |
| 置き場所 | exe の隣の DLL\(steam_api64.dll も同じ場所) |
| 読み込み | 各機能を最初に使う直前にエンジンが自動で読む。System.loadPlugin("name.dll") で先読みも可 |
| 検索パス | System.addPluginDirectory(path)(見本は "." と "DLL") |
| 許可リスト | System.setAllowedPlugins([...])。載っていない DLL は読み込まれない(空の一覧は制限なし) |
| ログ | Debug 実行モードの lumina_diag.log([プラグイン] の行)。Debug ビルドの exe は plugin_load.jsonl も出す |
6.8 セーブデータ仕様
| 種類 | API | 保存先 |
|---|---|---|
| スロットセーブ | System.saveData(slot) / SaveSlot | 保存先フォルダ |
| クイックセーブ/オートセーブ | SaveSlot.setSeries で履歴の番号と保持数を決める | 同上 |
| 前回の続きから | QuickResume オブジェクト | 同上 |
| 中断(サスペンド) | Suspend オブジェクト | 同上 |
| 設定・既読・システムフラグ | 自動 | systemdata.dat |
保存先は Config.txt の次の API で決めます。
| API | 意味 |
|---|---|
System.setSaveProduct(ブランド名, ゲーム名) | フォルダ分けに使う名前。両方とも省くと LUMINA / GameEngine |
System.setSaveRoot(ルート) | InstallPath / MyDocuments / MyGamesDocuments / AppData |
System.setSaveFolder(名前) | 末尾のフォルダ名(既定 save。見本は SaveData) |
System.setSaveDataId(ID) | 他の作品のセーブを読み違えないための印。セーブファイルの中に書いて照合する(フォルダ分けには使わない) |
System.setSaveDataMode(形式) | "" / "c" / "z"(6.2) |
| プラットフォーム | 保存先 |
|---|---|
| Windows | InstallPath = <exe のフォルダ>\<保存フォルダ>/MyDocuments = ドキュメント\<ブランド名>\<ゲーム名>\<保存フォルダ>/MyGamesDocuments = ドキュメント\My Games\<ブランド名>\<ゲーム名>\<保存フォルダ>/AppData = %APPDATA%\<ブランド名>\<ゲーム名>\<保存フォルダ>。InstallPath に書き込めないときは AppData へ回す(第3章 3.4) |
| ブラウザ | IndexedDB(IDBFS)。同じサイトに置いた別の作品と混ざらないよう <保存フォルダ>/<ブランド名>/<ゲーム名> で分け、ブラウザに永続保存(navigator.storage.persist)を求める |
| Android | アプリの内部ストレージ(<保存フォルダ>/<ブランド名>/<ゲーム名>) |
セーブデータの安全性
- セーブは一時ファイルに書き切ってから置き換えます(Windows)。書き込みの途中で落ちても、前のセーブは壊れません
- セーブから戻す画像・音のパスに UNC パス(
\\server\…)や..が含まれていれば、そのパスは使いません(ネットワークへの接続やフォルダ外の読み出しを防ぐ) - パックの目次は 256MB まで、画像の縦横は 16384 ピクセルまでに制限しています(6.3・6.5)
ロード・シーン戻りで戻るもの
セーブのロード、「前回の続きから」、シーン戻りでは、シナリオの位置と変数に加えて、背景・立ち絵・イベント CG・BGM・メッセージウィンドウの状態が戻ります。Windows・Android・ブラウザで同じです。
画面の保存(画面キャプチャー)
画面は PNG で保存します。
| 呼び方 | 保存のしかた |
|---|---|
System.captureScreen() | exe の隣の capture\ に capture_0001.png から連番で保存(上書きしない)。exe の隣に書き込めないときは、保存先フォルダの capture\ に保存 |
System.captureScreen("ask")、メニューの「画面キャプチャー」 | 保存先を選ぶ窓を出す。形式は PNG が既定(BMP も選べる) |
| プラットフォーム | 保存先 |
|---|---|
| Windows | 上の表のとおり |
| Android | アプリの内部ストレージの capture/ に PNG で保存 |
| ブラウザ | PNG をダウンロードとして渡す |
6.9 フラグシステム仕様
保存先の違う 4 種類の値を使えます(命令の詳細は 第10章)。
| 種類 | 値 | 保存先・寿命 | シナリオ命令 |
|---|---|---|---|
| シナリオ変数 | 整数(範囲の制限なし) | セーブデータごと。System.loadScenario で新しく始めると空になる(System.jumpScenario は保つ) | setvar 名前 値 / addvar 名前 値 |
| システムフラグ | 0〜9(範囲外は 0〜9 に収める。0 を入れると下ろせる) | systemdata.dat(どのセーブで立てても残る) | setsysflag 名前, 値 / addsysflag 名前, 値 |
| クリアフラグ | 真 / 偽 | systemdata.dat | setclearflag 名前, 値 |
| フローチャートフラグ | 0〜9(0 を入れると下ろせる) | systemdata.dat | setflowflag 名前, 値 / addflowflag 名前, 値 |
分岐はシナリオ変数を比べます。
if 変数 演算子 値 ラベル— 成り立てばラベルへ飛ぶ 1 行の分岐(ラベルの*は付けても省いてもよい。演算子は==!=<><=>=)#if "変数 演算子 値"〜#elif "…"〜#else〜#endif— 複数行のブロック(入れ子可)
システムスクリプトからは System.setSystemFlag / addSystemFlag / getSystemFlag / setClearFlag / getClearFlag / setFlowchartFlag / addFlowchartFlag / getFlowchartFlag / clearAllClearFlags を使います。
6.10 入力仕様
ADV 向け抽象入力(Input オブジェクト):
- 文字送り (
isAdvanceTextRequested) - スキップ (
isSkipRequested,isSkipHeld) - オート (
isAutoModeRequested) - バックログ (
isBacklogRequested) - システムメニュー (
isSystemMenuRequested) - クイックセーブ/ロード
- マウスジェスチャー(押している間に出る輪で、上下左右とホイール上に操作を割り当てる。
Input.setGestureAction(向き, 操作ID)。割り当てはInitialize.txtのsetupGestures) - タッチ(ブラウザ/Android): タップでクリック、500 ミリ秒の長押しで右クリック。3D アクションでは画面の左半分で移動、右半分で視線
- ゲームパッド(Windows・Android・ブラウザ): 下の表のとおり、決定・取り消し・移動などの操作として受け付ける
ゲームパッド
パッドで文章送り・選択肢・セーブ画面などを操作できます。割り当てはどの環境でも同じです。
| ボタン | 操作 |
|---|---|
| A | 決定(文章送り) |
| B / START | 取り消し・戻る(右クリック・Esc と同じ) |
| 十字キー / 左スティック | 上下左右の移動(押し続けると繰り返す) |
| LB | バックログ |
| RB(押し続ける) | スキップ |
| プラットフォーム | 受け付け方 |
|---|---|
| Windows | XInput 対応のパッド。ゲームの窓が前面にあるときだけ効く |
| Android | パッドに加えて、キーボードのキー(Enter・Esc・矢印キー・PageUp・Ctrl など)も同じ操作として受け付ける。端末の「戻る」ボタンはメニューの一覧を出す(確認・設定などの画面やバックログでは、その画面の「戻る」) |
| ブラウザ | ブラウザの Gamepad API で、最初に見つかったパッドを使う |
選択肢は十字キーで選んで A で決めます。Android / ブラウザでは、まだ選んでいないときに A を押すと、最初の選択肢に印が付きます。使うかどうかは Input.setGamepadEnabled(0 / 1)(既定は使う)、つながっているかは Input.isGamepadConnected() で調べられます。
汎用の画面のキー・パッド操作
Screen.show で出す画面(フローチャート・マップ・ステータス・育成シミュレーションの予定表など。Windows 以外では確認ダイアログも)は、キーとパッドでも操作できます。
- 矢印キー / 十字キーで、その向きにある近いボタンへ印を移す。印はマウスを乗せたときと同じ絵(hover の絵)で示す。押せないボタンは飛ばす
- Enter / A で印のボタンを決める。印が無いときの Enter / A は、まず最初のボタンに印を付けるだけ
- 右クリック・Esc・B で取り消す(何も選ばずに閉じる。確認ダイアログでは「いいえ」)
確認ダイアログのキー・パッド操作
確認ダイアログの「次回から確認しない」も、すべての環境でキーとパッドで操作できます。
| プラットフォーム | 操作 |
|---|---|
| Windows | 左右の矢印キー(十字キー)でボタン(はい・中断・いいえ)を選び、下でチェック欄へ、上でボタンへ戻る。Enter / A で選んでいる所を押す。チェック欄では入り切りだけで、ダイアログは閉じない。何も選んでいないときの Enter はこれまでどおり「はい」。選んでいるボタンはマウスを乗せたときと同じ絵、チェック欄は行全体を枠で囲んで示す |
| Android / ブラウザ | 上の「汎用の画面」と同じく十字キーで選ぶ。チェック欄も選べ、選んでいる間は枠で囲む。A で入り切りする(閉じない) |
6.11 コマンドライン引数(Windows)
| 引数 | 説明 |
|---|---|
--start-scenario=<パス> | ロゴとタイトルを飛ばし、このシナリオから始める(例 --start-scenario=scenario/sim_sample) |
--start-label=<ラベル> | 開始するラベル。シナリオの指定が無いときは、タイトルの「はじめから」で読むシナリオに使う |
--start-line=<行> | そのシナリオのソース行から始める |
--smoke-test-systemdata | 画面を出さずに systemdata.dat の作成・読み込み・保存だけを行って終了 |
--systemsave-mode=c / z | systemdata.dat の保存形式(暗号化/圧縮) |
System.switchArg(index, default, code0, code1, ...) で分岐可能。ブラウザはアドレスの ?KEY=VALUE、Android は launch.txt が環境変数の代わりになります(System.switchEnv で読めます)。
6.12 スクリプト言語仕様(概要)
システムスクリプト(LUMINA Script)
- 目印: 先頭に
// @lumina(旧表記// @tjsも可)。functionを使っていれば目印が無くても LUMINA Script として扱う。目印もfunctionも無いファイルは SimpleScript(1 行 1 呼び出し) - 変数:
var,let,const - 制御:
if/else,while,for,break,function/return - 型: null, bool, int, float, string, array, object
- 組み込み:
Math.*,JSON.*,Arrayメソッド
シナリオスクリプト
- 1 行 1 命令、本文はタブで始める
- 移動:
*ラベル,jump/goto,gosub/return - 分岐:
if 変数 演算子 値 ラベル,#if/#elif/#else/#endif - 注釈:
//から行末。;や(命令でない)#で始まる行もコメント
詳細は 第9章 システムスクリプト API と 第10章 シナリオ命令 を参照。