# DCS Mission Studio 0.4.0a6(アルファ版ビルド候補) 既存のDCSミッション(`.miz`)を、原本を残して編集するWindowsネイティブGUIです。独立した非公式ツールで、DCS開発元の承認・提携を意味しません。**純正エディターの全機能対応は開発中**です。飛行機能は対象外です。 - 機能ごとの状態と残る差: [対応表](FEATURE_MATRIX.md) - 実装順序と受入条件: [ロードマップ](IMPLEMENTATION_ROADMAP.md) - 検証の記録: [検証結果](QA_RESULTS.md)、DCS本体での確認手順: [DCS_VALIDATION.md](DCS_VALIDATION.md) ## 現在の状態(0.4.0a6、dev main 1fbb9ea から) - **版:** 0.4.0a6(アルファ版ビルド候補、dev main `1fbb9ea` から、ブランチ `release/0.4.0a6`)。dev main `1fbb9ea` に版の変更、リリースノート、文書の更新を加えたものです([リリースノート](RELEASE_NOTES_0.4.0a6.md))。0.4.0a6 は公開していません。公開している最新の版は 0.4.0a5 で、2026年10月28日に https://freedomflight.jp/dcs-mission-studio/ で公開した版です(告知はしていません。0.4.0a5 のビルドの記録は[リリースノート](RELEASE_NOTES_0.4.0a5.md))。 - **0.4.0a3 の後に加えたもの(画面と地図):** グループ編集タブを、左に検索・一覧・編集履歴、中央に地図、右に選んだグループの編集欄を置く形にしました。地図ではグループをドラッグして移動でき(離した時点で 1 回の履歴、ドラッグ中の Esc で取り消し)、地図と一覧の右クリックで、そのグループの操作をメニューから選べます。ミッションを開く前は、地図の上の「ミッションを始める」から開く・新規・合成デモを選べます。上のタブは 11 から 8 に減らし、元に戻す・やり直すをツールバーに置き、外観を Windows 11 に近づけました(`dcsmission/theme.py`。テーマのパッケージは使いません)。「トリガー」タブは ME と同じく、左のトリガー一覧(名前で絞り込み)で選んだトリガーの条件・アクションを右に出し、適用の後も選択と絞り込みを保ちます。「ブリーフィング」タブは 5 項目を一覧にしました。オンライン地図(既定はオフ)をオンにすると、OpenStreetMap の地図を概略図の下に描きます(下の「対応範囲と制限」の「オンライン地図」)。 - **0.4.0a5 の後に加えたもの(新規作成):** 新規作成ダイアログで、地形と陣営を ID の入力ではなく、DCS のインストールから読んだ一覧で選べます。インストールの一覧がないときは、地形名を入力します。ブルズアイと地図の中心は、地形の地図をクリックして置けます(`74d663e`、`08075d8`、`47469f7`。文書は `0763cee`)。西側の国の航空機・ヘリと、オンライン地図の速さは、下の「0.4.0a5 の後の修正」の項目にあります。 - **編集のコア:** `dcsmission/` のうち、0.4.0a3 から変えたのは画面のモジュール(`gui.py`、`map_view.py`、`theme.py`、`trigger_view.py` など)と、オンライン地図の `map_tiles.py`、設定の `settings.py`、自己診断の `smoke.py` です。0.4.0a6 では、西側の国の航空機の配置と複製のため、`aircraft_ids.py`、`placement.py`、`placement_dialog.py`、`editor.py`(複製の西側の呼出符号)も変えました。ミッションの読み書きのモジュール(`archive.py`、`lua.py`、`spatial.py` など)は変えていません。下の第10ラウンドの実データの計測は 0.4.0a6 より前のコードの記録で、0.4.0a6 の複製の変更については行っていません。 - **配布物の変化:** オンライン地図が標準ライブラリの `ssl` を使うため、Windows 版に OpenSSL の `libssl-3.dll` と `_ssl.pyd` が戻ります([依存一覧](DEPENDENCIES.md))。追加のパッケージはありません。 - **版の表記:** `dcsmission/__init__.py` は `__version__ = '0.4.0a6'` です。画面の範囲欄の見出しは「開発プレビュー 0.4.0a6(アルファ版)— 検証候補」と表示します(`gui.scope_heading`)。オンライン地図の User-Agent にもこの版を入れます。 - **ビルド:** 0.4.0a6 は `400a60a`(`release/0.4.0a6`)からビルドしました。GUI を含む全体試験は、ビルド元 `400a60a` で 2,504 件を実行し、失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0、tree_clean でした(証跡: `a6-400a60a-suite.json`、1,532 秒)。梱包監査 passed(ネイティブファイル 23、private findings 0)、構成要素の目録 16 件、凍結実行ファイルの自己診断 pass・11 項目(展開した ZIP からも pass)、アーカイブの検証 pass です。公開している 0.4.0a5 の Windows ZIP から、この 0.4.0a6 の Windows ZIP へのアプリ内の更新を、ループバックの試験用の取得元で確かめました(16 項目合格、証跡: `a6-field-update.json`)。サイズ・SHA-256・各証跡は[リリースノート](RELEASE_NOTES_0.4.0a6.md)にあります。 - **0.4.0a5 のビルド(公開版):** 0.4.0a5 の Windows ZIP とソース ZIP のビルド元は、dev main `e8a1cee` に版の変更と文書を加えた `release/0.4.0a5` のコミットです。0.4.0a5 は `e51793c`(`release/0.4.0a5`)からビルドしました。GUI を含む全体試験は、ビルド元 `e51793c` で 2,470 件を実行し、失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0、tree_clean でした(証跡: `a5-e51793c-suite.json`、1,055 秒)。梱包監査 passed(ネイティブファイル 23、private findings 0)、構成要素の目録 16 件、凍結実行ファイルの自己診断 pass・11 項目(展開した ZIP からも pass)、アーカイブの検証 pass です。サイズ・SHA-256・各証跡は[リリースノート](RELEASE_NOTES_0.4.0a5.md)にあります。2026年10月28日に https://freedomflight.jp/dcs-mission-studio/ で公開しました(告知はしていません)。更新の取得元の update.json は、2026年10月28日に、利用者が本番の鍵(ffs-update-2026a)で署名し、利用者の承認のうえ置きました(0.4.0a5 を指す。update.json の SHA-256 `8e023331475c000d9b276247ff68d63f853918c3d1d82abe91d2948d54ba8e38`)。(履歴: 0.4.0a4 は `9bf0118`(`release/0.4.0a4`)からビルドし、梱包監査・自己診断・アーカイブの検証に合格しました。ビルド元での GUI を含む全体試験は 2,372 件成功、失敗 0、エラー 0、スキップ 3、unraisable 0 です(`a4-9bf0118-suite.json`)。サイズと SHA-256 は[リリースノート](RELEASE_NOTES_0.4.0a4.md)にあります。2026年10月28日に https://freedomflight.jp/dcs-mission-studio/ で公開しました(告知はしていません)。) - **DCS 本体での確認:** 未通過です。Mission Editor での読込・再保存の確認は実施していません。0.4.0a5 で加えたのはアプリ内の更新で、ミッションの読み書きのモジュールは変えていません。0.4.0a4 で加えたのは画面と地図の表示ですが、地図のドラッグ移動は「移動・回転」の平行移動と同じ処理で、その出力も DCS では確かめていません。0.4.0a6 で加えた西側の国の航空機・ヘリの配置と複製、新規作成の地形の一覧も、DCS では確かめていません。DCS 互換は主張しません。 - **専用サーバーでの読み込み:** 第9ラウンドのコードの出力 37 ファイルの記録(`round9-server2-load.json`)が最新です。0.4.0a6 のコードの出力は、専用サーバーでも読み込んでいません。 - **テスト(0.4.0a6 の候補):** ブランチ `fix/map-speed-western` の最後に記録した GUI を含む全体試験は、`436366e` で 2,504 件を実行し、失敗 1、エラー 0、スキップ 3、unraisable 0 でした(証跡: `fix-436366e-suite.json`)。失敗は `test_updater` の `test_only_the_updater_imports_network_modules` で、`map_tiles.py` が接続の再利用のために `http.client`・`ssl`・`urllib.parse` を読み込むようになったためです。`d24028d` で許可に加え、`test_updater` の 81 件が成功しました。`d24028d` の後の全体試験は記録していません。dev main への統合の後、関連する試験 312 件が成功しました(作業記録。証跡ファイルはありません)。0.4.0a6 のビルド元の全体試験は、ビルド後にリリースノートに記入します。 - **テスト(0.4.0a5 までの記録):** 統合のコミット `1149fc5` の GUI を含む全体試験は 2,470 件、失敗 1、エラー 0、スキップ 3、unraisable 0、tree_clean でした(`merge-1149fc5-suite.json`)。失敗は `test_gui_update` の `test_menus` で、更新の項目が設定メニューの先頭にあると前提していたためです(統合後は、main の設定メニューの末尾に付きます)。試験を `e8a1cee` で直し、`test_gui_update` の 17 件が成功しました。0.4.0a5 は `e51793c`(`release/0.4.0a5`)からビルドしました。GUI を含む全体試験は、ビルド元 `e51793c` で 2,470 件を実行し、失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0、tree_clean でした(証跡: `a5-e51793c-suite.json`、1,055 秒)。梱包監査 passed(ネイティブファイル 23、private findings 0)、構成要素の目録 16 件、凍結実行ファイルの自己診断 pass・11 項目(展開した ZIP からも pass)、アーカイブの検証 pass です。サイズ・SHA-256・各証跡は[リリースノート](RELEASE_NOTES_0.4.0a5.md)にあります。統合の各段階の全体試験(GUI を含む)は、画面の流れ `6a34bd0` 2,323 件、オンライン地図 `0ab6cff` 2,341 件、OpenSSL の同梱を統合した dev main `63b8376` 2,341 件、トリガー・ブリーフィングのタブ `b576e57` 2,354 件で、いずれも失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0、tree_clean です(`ui-flow-6a34bd0-suite.json`、`online-map-0ab6cff-suite.json`、`main-63b8376-suite.json`、`ui-bt-b576e57-suite.json`)。地図を主役にしたタブを含む 0.4.0a4 のビルド元 `9bf0118` では 2,372 件成功、失敗 0、エラー 0、スキップ 3、unraisable 0、tree_clean です(`a4-9bf0118-suite.json`)。 - **0.4.0a5 の後の修正(ブランチ `fix/map-speed-western`。dev main `1fbb9ea` で統合済み、0.4.0a6 に含む):** オンライン地図の読み込みを速くし(タイルは届いた順に表示、ズーム直後は半解像度の下描きと上の段の拡大、通信は接続の再利用)、西側の国の航空機・ヘリを配置できるようにしました。複製では、西側の呼出符号を次の空き番号へ振り直します(下の「航空機・ヘリの配置」と「複製」)。DCS 本体での確認は未実施です(西側の国の航空機の出力も、DCS 本体でも専用サーバーでも読み込んでいません)。 - **アプリ内の更新:** 0.4.0a6 は、0.4.0a5 の利用者がアプリ内の更新(「ヘルプ › 更新を確認...」)で受け取れる最初の版です。公開と update.json の配置は、利用者の承認のあとに行います。この文書の更新時点では、0.4.0a6 は公開しておらず、update.json は 0.4.0a5 を指したままです。0.4.0a4 以前の利用者は、ZIP を手で入れ直します。 - **0.4.0a2 の不具合(保存でメンバー名が変わる):** 0.4.0a3 で直しました(下の「0.4.0a3 の時点の状態」)。0.4.0a2 で保存したミッションの扱いは、[0.4.0a3 のリリースノート](RELEASE_NOTES_0.4.0a3.md)にあります。 ## 0.4.0a3 の時点の状態(履歴、dev main 6d72a0d 基準) この節は 0.4.0a3 の README の記述です。0.4.0a3 はその後、2026年10月24日に公開しました。 - **版:** 0.4.0a3(アルファ版ビルド候補、dev main `6d72a0d` から)。開発リポジトリの dev main `6d72a0d`(第10ラウンドの統合)に、版の変更、リリースノート、文書の更新を加えたものです([リリースノート](RELEASE_NOTES_0.4.0a3.md))。0.4.0a3 は公開していません。前の版の 0.4.0a2 は、2026年10月23日に公開した版です(下の「0.4.0a2 の時点の状態」)。 - **0.4.0a2 の不具合(保存でメンバー名が変わる):** 公開中の 0.4.0a2 は、保存のたびに ZIP メンバー名の生バイトと UTF-8 フラグ(0x800)を書き換えます(それ以前の 0.4.0 系のコードも同じ書き方です)。同梱ミッション 2,623 件の無変更保存では、名前かフラグが変わるメンバーが 37,011、保存後に解決できなくなる資源参照(中国語のロケールのブリーフィング画像など)が 19 件ありました(作業記録)。0.4.0a3 は読み込んだとおりの名前とフラグで書き、同じ 2,623 件で変化 0、資源参照の解決は保存の前後とも 44,742 件です(`round10-postmerge-names2623.json`)。DCS で画像が実際に表示されなくなるかは確認していません。 - **0.4.0a2 の後に加えた機能(第10ラウンド):** 経路表での ETA の再計算(保存済みの ETA が純正エディターの規則と一致する時刻付きの経路だけ)、トリガーの条件・アクションの引数の編集と、条件・アクション・トリガーの削除・並べ替え(「トリガー」タブの「引数・構造を編集…」)、経路点の AI タスクの数値オプション 4 種、保存の失敗の報告の型付け(`SaveIOError`)、ZIP メンバー名の保持、トリガーゾーンの名前の宣言をグループ・ユニット名の参照として数えない修正。 - **ビルド:** 0.4.0a3 の Windows ZIP とソース ZIP は `903954d`(`release/0.4.0a3`)からビルドし、梱包監査・自己診断・アーカイブの検証に合格しました。サイズと SHA-256 は[リリースノート](RELEASE_NOTES_0.4.0a3.md)にあります。 - **版の表記:** `dcsmission/__init__.py` は `__version__ = '0.4.0a3'` です。画面の範囲欄の見出しは `__version__` から組み立て、「開発プレビュー 0.4.0a3(アルファ版)— 検証候補」と表示します(`gui.scope_heading`)。 - **アプリ内の更新(ブランチ `feat/self-update`。この節は 0.4.0a3 の時点の記述で、現在は dev main e8a1cee に統合済み。どの ZIP にも入っていませんでした):** 「ヘルプ › 更新を確認...」と「設定 › 起動時に更新を確認する」(初期値はオフ)を加えました。https の署名つき `update.json`(Ed25519。ブランチ `feat/signed-updates` で署名の検証を追加)を読み、新しい版の ZIP を取得して SHA-256 を確かめ、同じフォルダーのまま中身を入れ替えて起動し直します(下の「更新」の節)。`update.json` は、0.4.0a5 の公開のあと 2026-10-28 に配布サイトに置きました(この節を書いた時点では未配置でした)。公開中の 0.4.0a2 と、0.4.0a3 の ZIP には更新機能がないため、更新機能の入った最初の版は、配布ページの ZIP から手で入れ直す必要があります。 - **DCS 本体での確認:** 未通過です。原本から作った出力を DCS の Mission Editor で開き、再保存して比較する手順は実施していません。検証キットは用意済みですが、第10ラウンドの機能の項目はありません(「検証」の節を参照)。DCS 互換は主張しません。 - **専用サーバーでの読み込み:** 第9ラウンドのコードの出力 37 ファイルの記録(`round9-server2-load.json`)が最新です。第10ラウンドのコードの出力は、専用サーバーでも読み込んでいません。 - **テスト:** 第10ラウンドの統合ブランチ `9f7d230`(そのツリーは dev main `6d72a0d` と同一)で、GUI を含む全体試験は 2,310 件成功、失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0 です(`round10-merged-suite.json`)。0.4.0a3 のビルド元での試験の記録は、ビルドの後にリリースノートに載せます。 - **編集を含む保存の往復:** dev main `6d72a0d` で、同梱ミッションの標本 112 件に代表的な編集(グループ・ユニットの改名、円ゾーンの追加、グループの周波数、日時・静的気象の整数項目、気象の追加項目の数値、ブリーフィング、ユニット追加、グループ削除)を加えて保存し、再読込と undo まで確かめました。112 件すべて合格で、失敗の項目はすべて 0 です(`round10-postmerge-rt112.json`。JSON にコミットの記録はなく、`6d72a0d` は作業記録)。 - **同梱ミッションの読取走査:** 開けた件数・無変更の往復の一致・原本の不変の全件計測は、第7ラウンド統合時の `corpus-round7-1b6f3ca.json`(いずれも 2,623)が最新です。第10ラウンドの名前の計測(上)は 2,623 件を開いて無変更で保存しましたが、比べたのはメンバー名・フラグと資源参照です。 ## 0.4.0a2 の時点の状態(履歴、main 575210a 基準) この節は 0.4.0a2 の README の記述です。0.4.0a2 には、上の「0.4.0a2 の不具合(保存でメンバー名が変わる)」があります。 - **版:** 0.4.0a2(アルファ版ビルド候補)。開発リポジトリの main `575210a` に、公開前の文字列の整理と版の変更を加えたものです([リリースノート](RELEASE_NOTES_0.4.0a2.md))。前の 0.4.0a1(`936b1c0`)の ZIP は作成・検証済みで公開していません([0.4.0a1 のリリースノート](RELEASE_NOTES_0.4.0a1.md))。下の「0.4.0a1 の後に加えた機能」は 0.4.0a1 の ZIP には含まれず、0.4.0a2 に含まれます。(履歴: 0a1abca の時点では「ソースの `__version__` は 0.4.0a1 のままです」でした。) - **0.4.0a1 の後に加えた機能:** トリガーのメッセージ文言の編集、無線プリセット(既存チャンネルの周波数)、経路点の AI タスク(既存オプションの値と有効/無効)、航空機・ヘリの空中開始の配置(東側の国のみ)、操作できる座標概略図と、DCS の地形データ・同梱の Natural Earth による町・飛行場・ビーコン・海岸線・国境の重ね描き、KML / GeoJSON の書き出し。トリガーの照合(SCHEMA の拡張と ME の版規則、保存時の剪定の検出)も広げました。 - **ビルド:** 0.4.0a2 の Windows ZIP とソース ZIP を `cca840c` から作成・検証しました。サイズと SHA-256 は[リリースノート](RELEASE_NOTES_0.4.0a2.md)にあります。2026年10月23日に https://freedomflight.jp/dcs-mission-studio/ で公開しました(告知はしていません)。(履歴: `707c082` のローカルビルドは監査と凍結版の自己診断を通過し、ZIP は作っていませんでした。) - **版の表記:** `dcsmission/__init__.py` は `__version__ = '0.4.0a2'` です。画面の範囲欄の見出しは `__version__` から組み立て、「開発プレビュー 0.4.0a2(アルファ版)— 検証候補」と表示します(`gui.scope_heading`)。 - **DCS 本体での確認:** 未通過です。原本から作った出力を DCS の Mission Editor で開き、再保存して比較する手順は実施していません。検証キットは用意済みです(「検証」の節を参照)。DCS 互換は主張しません。 - **専用サーバーでの読み込み:** 第9ラウンドのコードの出力 37 ファイルを、利用者が運用する DCS の専用サーバーで読み込み、それぞれ 30 秒動かして、すべて合格しました(`round9-server2-load.json`)。Mission Editor での確認の代わりにはなりません。 - **テスト:** 0.4.0a2 のビルド元 `cca840c` で、GUI を含む全体試験は 2,054 件成功、失敗 0、エラー 0、スキップ 3(シンボリックリンクの権限)、unraisable 0 です(`a2-cca840c-suite-display2.json`。ウィンドウを2台目のモニターに出して実行)。配布版は監査(passed)、凍結版の自己診断(10 項目、pass)、ZIP の検証(pass)を通過しています([リリースノート](RELEASE_NOTES_0.4.0a2.md))。それまでの記録: main `0a1abca` と同じツリーの 2,026 件(`geo-map-suite-3.json`)。GUI を除く試験は、この文書の更新時に 1,512 件成功、スキップ 3 でした(証跡ファイルなし)。 - **同梱ミッションの読取走査:** 2,623 件が開き、無変更の往復が一致した件数は 2,623、原本が変わらなかった件数は 2,623 です(第7ラウンド統合時の `corpus-round7-1b6f3ca.json`。件数は `corpus-3da759e.json` と同じ)。読取と無変更保存の計測で、編集後の保存の往復は検証していません。第8ラウンド以降の再計測は未実施です。 ## 0.4.0a1 ビルド候補の時点の状態(履歴、main f3caf88) - **版:** 0.4.0a1(アルファ版ビルド候補、未公開)。基準は main の `f3caf88` です。 - **ビルド:** ローカルで PyInstaller によりビルドし、監査(passed)と凍結版の自己診断(9 項目、pass)の記録があります。Windows の ZIP は未作成で、公開は未承認です(その後、最終ビルド `936b1c0` で ZIP を作成・検証しました)。 - **テスト:** GUI を含む全体試験は 1,517 件成功、失敗 0、スキップ 3(シンボリックリンクの権限)、unraisable 0 です(`round6-merged-suite.json`、git head `a8bb2fb`)。`f3caf88` そのものの GUI を含む試験は未実施です。 - **同梱ミッションの読取走査:** 2,623 件が開き、無変更の往復が一致した件数は 2,623、原本が変わらなかった件数は 2,623 です(`corpus-3da759e.json`)。 ## 0.4.0-dev 時点の現況(履歴、main b2837b1) - **版:** 0.4.0-dev(未リリースソース)。Windows の EXE / ZIP は作成していません。保全済みの 0.3.0 / 0.2.0 のバイナリには、この版の変更が含まれません。 - **アプリ内の表示:** ソースの版番号(`dcsmission/__init__.py`)と画面内の案内文は、まだ 0.3.1 の表記です。この README の記述が 0.4.0-dev の現況です。 - **DCS本体での確認:** 未通過です。原本から作った出力を DCS の Mission Editor で開き、再保存して比較する手順は実施していません。DCS 互換は主張しません。 - **テスト:** Python 3.13.5 で実行した記録です。GUI を含む全体試験は、main 89c6350 のツリー(作業記録では 35d8c8c で実行)で 1,415 件、失敗 0、スキップ 2、unraisable 0 です(証跡: round5b-merged-suite.json)。main b2837b1 との差は dcsmission/spatial.py の docstring と qa/ の検査スクリプト(独立経路表 GUI 検査の複写、Lua 5.1 判定、報告欄)だけです。tests/ と dcsmission/ の他のファイルは無変更です。b2837b1 そのものの全体試験の記録はまだありません。作業記録の 1,161 件(round45-merged-suite.json)と、0.4.0-dev の中間記録 793 件(round3-merged-suite.json)は履歴として残しています(下の「記録」を参照)。 - **同梱ミッションの読取走査:** ローカルの DCS 同梱ミッション 2,623 件を読取専用で走査しました(証跡: corpus-3da759e.json。probe の git head は b2837b1、計測コードは 3da759e)。開けたのは 2,623 件、往復の不一致の分類は空、無変更の別名保存でメンバーのバイト列が一致したのは 2,623 件、原本が変わらなかったのは 2,623 件です。読取と無変更保存の計測で、編集後の保存の往復は検証していません。旧計測(corpus-round6.json、git head d43b9fe)は履歴として残しています。 - **0.3.1 で開けなかった 111 件:** ZIP 拡張フィールドの不一致 98 件、重複メンバー名 10 件、Lua ノード上限 3 件でした。上の計測では、これらを含む 2,623 件が開きました。 - **統合ブランチでの標本計測:** ZIP 修正の取り込み後(その後の変更は含まない)に、同梱ミッションの標本 340 件で、ゾーン追加を undo すると原文に戻ったのは 340 件、配置追加を保存して再読込し undo すると原文に戻ったのは 339 件でした。残る 1 件は国が陣営の国テーブルに無いため、意図どおり拒否されました(証跡: round4-postmerge.json)。 ## できること(dev main 1fbb9ea) - 既存 `.miz` を開き、バックアップ付きで別名保存する。編集は履歴(元に戻す/やり直し)で扱う。 - グループの複数選択で通信周波数・変調を一括変更する。単純なグループを複製する。 - 航空機・ヘリコプターの無線プリセットで、既存チャンネルの周波数を変更する(グループ編集タブの「無線プリセット…」。1ユニット、または同じ機種の全ユニット)。 - 経路点の AI タスクで、既存のオプションの値(列挙値・フラグと、第10ラウンドからは数値オプション 4 種)と、既存エントリの有効/無効を変更する(グループ編集タブの「AI タスク(経路点)…」。飛行機・ヘリ・車両・艦船のグループ)。 - グループ名・ユニット名を変更する。他の場所に同じ名前があれば一覧で示し、既定の「いいえ」で止まる。承認した場合も参照は変えず、履歴に明記する。 - グループを削除する。ユニットを追加・削除する(追加は航空機・艦船以外、削除は1体以上残る場合)。ID で参照されているものは削除を拒否する。 - 日時・静的気象、通常の航路の数値(2点目以降)を編集する。 - 経路表で、通常の航空経路の3点目以降を追加・削除・並べ替える(実ミッションの一部。スクリプトを含む経路は確認が必要)。時刻付きの経路(点3以降に 0 以外の ETA か ETA ロックがある経路)は、保存済みの ETA が純正エディターの規則と一致する場合だけ編集し、同じ履歴で ETA を再計算する(第10ラウンド)。 - 開始位置(経路点1)を移動する。グループ・全ユニット・経路点1を1操作で動かす。 - 選択したグループを平行移動・回転する(対応する形状のみ)。 - ゾーンの追加(円・四角形)、改名(参照の確認つき)、四角形の頂点の移動、削除。既存の円形ゾーン(中心・半径)と非リンク多角形ゾーン(平行移動)の編集。 - 地上車両・艦船・静的グループの追加と、航空機・ヘリコプターの空中開始の追加(「グループを追加…」。航空機・ヘリは、開いているミッションにある機種だけ。西側の国は、同じ国・同じ機種の機体がミッションにある場合だけ)。 - 日時・静的気象と、その追加項目(雲、降水、霧、砂塵、ハロー、地表乱流)の編集(気象パネル)。 - トリガーの表示と、メッセージの文言の編集(「トリガー」タブの「文言を編集…」。辞書にある文言だけで、トリガーの設定と trig は変えない)。 - トリガーの条件・アクションの引数(ユニット・グループ・ゾーンの参照先、整数、小数、真偽、フラグ、選択肢)の変更と、条件・アクション・トリガーの削除・並べ替え(「トリガー」タブの「引数・構造を編集…」。保存された trig が規則からの生成結果と一致するミッションだけ。trig も同じ履歴で書き換える。第10ラウンド)。 - 座標概略図(北が上。パン・ズーム、クリックでグループを選択、ドラッグで移動、右クリックで操作メニュー)。DCS のインストール先を設定すると、町・飛行場・ビーコンと海岸線・陸上国境を重ねて表示し、ファイル メニューの「地図データを書き出す(KML / GeoJSON)…」で書き出せる。 - オンライン地図(既定はオフ): 概略図の上のチェックか「設定」メニューでオンにすると、確認のあと、OpenStreetMap の地図を概略図の下に、DCS の地形の緯度経度に合わせて描く(DCS のインストール先が必要)。 - 読取専用の参照検査、基本設定、ブリーフィング、空の新規構造候補。 - 新規作成で、DCS のインストールにある地形と陣営を一覧から選ぶ(インストールの一覧がないときは地形名を入力)。ブルズアイと地図の中心は、地形の地図をクリックして置く。 - 未保存の編集の復旧: 起動時に残っている復旧ファイルを一覧し、選んだものだけを未保存のミッションとして開けます。自動では復元しません。 - 設定の保存: インストール先を保存し、次回起動時に読み直します。型収集フォルダーも保存し、次回の選択で初期位置にします。 - アプリ内の更新(`feat/self-update`): 「ヘルプ › 更新を確認...」で新しい版を確かめ、取得と検証のあと、同じフォルダーのまま入れ替えて起動し直します。起動時の確認は、設定でオンにした場合だけです(24 時間に 1 回)。 ## 未実装の機能(dev main 1fbb9ea) - 駐機・滑走路・空母からの開始の配置。西側の国で、同じ国・同じ機種の機体がミッションにない場合の航空機の配置(呼出名の一覧がインストールにないため)。航空機・ヘリ・艦船のユニット追加。 - トリガー・条件・アクションの追加(作成)。保存された trig が規則からの生成結果と一致しないミッションでの、引数と構造(削除・並べ替え)の編集。保存されていない引数の追加。共有された文言やスクリプトが参照する文言の編集。 - AI タスクの追加・削除・並べ替え、目標種別・編隊・兵装種別のオプション、高度制限(ALT_RESTRICTION_MIN / MAX)の値、目標・座標の変更。 - 無線チャンネル・無線の追加・削除、変調・チャンネル名の変更、機種ごとの周波数範囲の確認。 - 離陸・着陸の固定点を含む経路の構造編集。保存済みの ETA が純正エディターの規則と一致しない時刻付きの経路の構造編集(同梱ミッションの計測では、時刻付きの経路の半数以上が一致しない。作業記録)と、routeRelativeTOT の経路。 - ローカライズ名(`DictKey_`)のグループ・ユニットの複製。 - 起動をまたぐ経路表の確認の記憶(現在は開いている文書の間だけ)。 - 衛星画像・地形の起伏の表示(地図はオンライン地図の OpenStreetMap の標準地図だけ)。 (履歴: 0.4.0a1 の時点では、ここに「航空機の新規配置。配置は航空機とヘリコプターを拒否します。」と「画面の範囲欄の版表記の統一」がありました。前者は第8ラウンドで東側の空中開始に限って実装し、後者は f4d3497 で済んでいます。) (履歴: 0.4.0a2 の時点(main 0a1abca の記述)では、ここに「トリガーの条件・アクションの作成・削除・並べ替えと引数の編集。」「AI タスクの追加・削除・並べ替え、数値・目標種別・編隊・兵装種別のオプション、目標・座標の変更。」「離陸・着陸の固定点を含む経路の構造編集、ETA の再計算。」がありました。第10ラウンドで、トリガーの削除・並べ替えと引数の編集、数値オプション 4 種、規則と一致する経路の ETA の再計算を実装しました。) ### 履歴: b2837b1 時点の GUI 未配線の一覧 以下は b2837b1 時点の記述です。復旧ファイル、履歴破棄の注記、経路表の確認の記憶、設定の保存は、f3caf88 で GUI に接続済みです。 - コアはあり、テストもあるが、GUI に未配線の機能: 復旧ファイル(`recovery.py`)。起動時の一覧、復元・破棄の確認、保存後の定期書込は未実装です。自動復元はしません。履歴破棄の警告(`Editor.history_truncated`、`dropped_history_labels`)も、GUI はまだ破棄を警告しません。 - main にまだ実装がない機能: 経路表の確認のミッション単位の記憶(現状は作業ごとに確認します)。設定の保存(インストール先は読取専用で、セッション内だけ保持します)。 ## 起動 ソースから起動します。Python 3.13(Tk 付き)を使い、リポジトリのルート(この README のあるフォルダー)で実行してください。 ```text python -B -m dcsmission ``` `-B` は .pyc を作りません。自己診断は次のとおりです。出力先の JSON 名は新しいものを指定してください(既存のファイルは上書きしません)。 ```text python -B -m dcsmission --self-test <新しい名前.json> ``` 公開している Windows の ZIP は 0.4.0a5 です(2026年10月28日公開。サイズと SHA-256 は[リリースノート](RELEASE_NOTES_0.4.0a5.md))。アプリ内の更新を含む最初の版です。(履歴: 0.4.0a5 の公開の前は「公開している Windows の ZIP は 0.4.0a4 です(2026年10月28日公開)。その ZIP には、上の「0.4.0a3 の後に加えたもの」(画面と地図)は含まれますが、アプリ内の更新は含まれません。」でした。)0.4.0a5 は、アプリ内の更新を含む最初の版です。(履歴: 0.4.0a3 の時点では「公開している Windows の ZIP は 0.4.0a2 です(2026年10月23日公開)。その ZIP には第10ラウンドの機能と名前の保持の修正は含まれず、上の「0.4.0a2 の不具合」があります。」でした。)Windows の ZIP(0.4.0a1)は最終ビルド `936b1c0` で作成・検証済みで、公開していません(サイズと SHA-256 は[リリースノート](RELEASE_NOTES_0.4.0a1.md))。その ZIP には、0.4.0a1 の後に加えた機能は含まれません。ZIP を使う場合は、`DcsMissionStudio.exe` と `_internal`、`licenses` を含むフォルダー全体を展開し、公開時に添える SHA256SUMS.txt で確かめてから使ってください。(履歴: f3caf88 の時点では「Windows の ZIP(0.4.0a1)は、まだ作成していません。」「SHA256SUMS.txt は未作成です」、0.4.0-dev の時点では「Windows の EXE / ZIP は 0.4.0-dev では作成していません。」でした。)0.3.0 の ZIP を使う場合は、フォルダー全体を展開して `DcsMissionStudio.exe` を起動します。その ZIP は 0.4.0-dev の変更を含みません。 ## 操作 画面の構成: 「グループ編集」タブは、左に検索・「グループを追加…」・一覧・編集履歴、中央に概略図(地図)があります。ミッションを開く前は、地図の上の「ミッションを始める」から開く・新規・合成デモを選べます。地図ではグループをクリックで選び、ドラッグで移動します(離した時点で 1 回の履歴。ドラッグ中の Esc で取り消し、Ctrl+Z で戻せます)。移動の規則は「移動・回転」タブの平行移動と同じで、移動できないグループを含む選択は動かず、ポインターの横に理由を出します。空いた所のドラッグは表示位置の移動です。地図と一覧の右クリックで、名前の変更・複製・コピー・貼り付け・航路・開始位置・無線プリセット・AI タスク・ユニット・削除をその場のメニューから選べます(使えない項目は右の欄のボタンと同じく無効)。地図の空いた所の右クリック「ここにグループを追加…」は、その位置を X / Y の初期値にして追加ダイアログを開きます。一覧のダブルクリックで地図をそのグループへ移し、一覧では F2 で名前の変更、Delete で削除を開きます。右は選んだグループの編集欄で、「操作」(無線・名前・複製・削除・開始位置・ユニット・AI タスク)、「航路」「基本設定」「移動・回転」のタブに分かれています。左で別のグループを選ぶと、右の欄はその場で対象が替わります。ミッション全体の項目は上のタブ(日時・静的気象、ゾーン、ブリーフィング、トリガー、参照検査、ミッション構造)です。元に戻す・やり直すはツールバー、DCS のインストール先と型の収集は「設定」メニューかウィンドウ下端の「DCS: …」「型: …」から変更します。 1. 「ミッションを開く」で `.miz` を選びます。「合成デモで試す」(地図の上の「ミッションを始める」、または ファイル メニュー)では同梱素材を使わず操作を試せます。デモは DCS 互換確認済みの飛行ミッションではありません。 2. 一覧で Ctrl / Shift を使って複数選択します。周波数の欄の下に、選んだグループの現在の値が出ます(入力した値は選び直しても消えません)。 3. 「グループを削除…」「ユニットを削除…」は、実行前に参照を検査します。確認画面で内容を見てから実行します。グループ削除の確認画面は既定が取消です。 4. 「名前を変更…」「ユニット名を変更…」で改名します。他の場所で名前が使われていれば確認が出ます。既定は「いいえ」です。 5. 「経路表(追加・削除・並べ替え)…」は、航空機・ヘリコプターのグループを1つだけ選んだ状態で開きます。点1・点2は読み取り専用です。適用を押すまで変更されません。このグループの航路に未適用の入力がある場合は、適用または破棄してから開いてください。同じ開いている文書の中では、同じ元ファイルと同じ危険の要約の確認は、もう一度求めません(アプリの起動中だけ。保存しません)。時刻付きの経路は、保存済みの ETA が純正エディターの規則と一致する場合だけ変更でき、適用すると ETA を再計算します。変更できない場合は理由を表示します。 6. 「開始位置の移動…」は、移動可能なグループだけで有効です。機首・psi は条件を満たすときだけ更新されます。ETA は再計算しません。 「無線プリセット…」(飛行機・ヘリ)と「AI タスク(経路点)…」(飛行機・ヘリ・車両・艦船)は、グループを1つ選んだ状態で開きます。変更できない項目は理由を表示し、「適用」を押すまで変更されません。「トリガー」タブは ME と同じ並びで、左のトリガー一覧(名前で絞り込めます)で選んだトリガーの条件・アクションを右に表示します。メッセージのアクションを選んで「文言を編集…」を押す(行のダブルクリックか Enter でも開きます)と文言を変更できます(Enter で改行、Ctrl+Enter で適用)。トリガー・条件・アクションの行を選んで「引数・構造を編集…」を押すと、そのトリガーの引数を変更し、条件・アクション・トリガーを削除・並べ替えできます(引数は「適用」でまとめて 1 回の履歴、削除・並べ替えは 1 回ずつ適用します)。保存された trig が生成結果と一致しないミッションでは、タブの上にその旨を示し、このボタンは押せません。適用した後も、選んでいたトリガーと行、絞り込みはそのまま残ります。「ブリーフィング」タブでは、左の一覧で項目を選んで右で本文を編集します(一覧の「状態」に編集可・読み取り専用・下書きを表示)。概略図のグループをクリックすると、一覧でそのグループが選ばれます。 7. 「航路」「基本設定」(グループ編集の右側)と「日時・静的気象」「ゾーン」「ブリーフィング」では、変更した項目を「変更した項目を適用」するまで保存に含まれません。「日時・静的気象」は、左の「日時・気温・風」と右の「雲・霧・砂塵など」を、それぞれの欄のボタンで別々に適用します。 8. 元に戻す/やり直しで操作を取り消せます。「別名保存」で出力し、DCS 本体のエディターで内容を確認してください。 「新規 / New」または文字入力欄以外で`Ctrl+N`を押すと、新規作成ダイアログが開きます。地形と日付を選ぶか入力し、開始時刻(時:分)・国ID・ブルズアイ・地図中心・静的気象・5項目の文章を確認して「作成」を選びます。DCS のインストール先を指定していると、地形はインストール済みの一覧から選べ、「DCS の標準の陣営に分ける」で赤・青の国IDがまとめて入り(国名も表示)、ブルズアイと地図中心は「位置」タブの地形の地図をクリックして置けます(飛行場の近くでは飛行場の位置)。日本語/Englishの切替は新規フローに対応し、既存アプリ全体は日本語です。入力エラーではダイアログと入力を保持し、取消では既存文書を変更しません。既存の未保存編集・ブリーフィング下書きがある場合は確認してから文書を交換します。 作成直後は初回保存前として扱い、編集をundoで初期状態に戻しても離脱時に保存を確認します。保存は明示的な「別名保存」のみです。保存先の取消や保存失敗では未保存状態を保持します。操作と入力項目は[新規作成GUI](NEW_MISSION_GUI.md)、データ契約は[新規生成API](NEW_MISSION_API.md)を参照してください。 `Ctrl+N` 新規、`Ctrl+O` 開く、`Ctrl+Shift+S` 別名保存、`Ctrl+Z/Y` 取消/やり直し。一覧で `Ctrl+A/C/V/D` 全選択/コピー/貼付/複製。文字入力欄では通常の文字編集操作を保ちます。 ## 保護と復旧 原本と同じパス、およびそのハードリンク等への保存は禁止しています。別名出力を上書きする場合は、明示確認後に`出力名.<ランダムID>.bak`を作ります。必要ならアプリを閉じてバックアップを別の`.miz`名へコピーし、DCSで内容を確認してください。 出力と同じフォルダーの一時ファイルへ書き、ZIPとLua構造を再検証してから保存します。失敗時は編集内容・履歴と既存出力を保持します。OS の入出力の失敗(一時ファイルの作成・書込・fsync、バックアップの作成、検証の再読込、置換)は `SaveIOError` として報告し、消せなかった一時ファイル、残した完全なバックアップ、消せなかった不完全なバックアップ(出力の復元に使ってはいけないもの)があれば、その場所を示します(第10ラウンド)。ZIP メンバーの名前は、読み込んだときの生バイトと UTF-8 フラグのまま書きます(0.4.0a2 までは書き換えていました。上の「0.4.0a2 の不具合」)。元の読込元は別名保存後も変わりません。未保存の編集は、編集中に復旧ファイルへ書き出します(最後の変更から30秒後、最長120秒後まで)。復旧ファイルは利用者のアプリデータのフォルダー(`%LOCALAPPDATA%\DcsMissionStudio\recovery`)に置き、原本の隣やリポジトリには置きません。起動時には、残っている復旧ファイルを一覧するだけです。自動では復元しません。「ファイル › 復旧ファイル…」で、選んだものだけを「復旧して開く」(未保存の文書として開き、原本へは上書きしません)か「破棄」できます。原本が復旧の作成後に変わっていた場合、復旧は拒否されます。保存に成功すると、その編集の複製は消えます。未保存の変更を破棄して文書を閉じた場合も、書込が5秒以内に終われば複製は消えます。復旧した複製は、保存しても消えず、利用者が破棄するまで残ります。クラウド同期の場所と判定されるフォルダー(OneDrive、Google Drive、Dropbox、iCloud Drive などの同期フォルダー名を含むパス、OneDrive の環境の場所、プロジェクトのフォルダー)では復旧コピーを書かず、起動時にその旨を表示します。原本の経路を持たない新規作成の未保存ミッションには、復旧コピーを作りません。復旧ファイルの完全性は改ざん耐性ではありません。(b2837b1 時点では「GUI からの一覧・復元・破棄はまだありません」でした。)履歴は100操作/約64MiBまでです。上限を超えると古い操作から破棄し、破棄の事実と破棄された操作名を Editor に記録します(`history_truncated`、`dropped_history_labels`)。GUI は、破棄があった文書で注記を出します(ステータス欄には文書ごとに一度だけ通知し、注記欄と取り消しメニューの表示は破棄がある間続きます)。(b2837b1 時点では「現在の GUI は、この破棄をまだ警告しません。」でした。)1操作がメモリ上の文字列で64MiBを超える場合は、その操作を拒否します。取り消し・やり直しは、現在の文書が履歴の先頭と一致する場合だけ働きます。履歴の容量は、メモリ上の文字列の大きさで計算します。 読込中はウィンドウ下端に出る「読込を取り消す」で結果の採用を取り消せます。処理中の読取自体は安全な区切りまで続きます。保存途中の強制終了は避けてください。変更がある状態で閉じる場合は保存・破棄・取消を選べます。 ## 更新(アプリ内) この節の機能は `feat/self-update` と、その上に署名の検証を加えた `feat/signed-updates` のもので、dev main e8a1cee に統合しました。0.4.0a4 までの ZIP には入っていません(0.4.0a5 が初めて含む版)。 - **通信する場面:** 「ヘルプ › 更新を確認...」を押したときと、「設定 › 起動時に更新を確認する」をオンにしたときの起動後の確認だけです。起動時の確認は初期値がオフで、オンでも最後の確認から 24 時間以上たっているときだけ、画面が出たあとに裏で行います。それ以外は通信しません。取得元は https://freedomflight.jp/updates/dcs-mission-studio/update.json(パスやトークンは要りません。2026-10-28 に、0.4.0a5 を指す署名つきの update.json を置きました)で、https 以外の取得元とリダイレクト先は拒否します。資格情報は送りません(User-Agent に版名を入れるだけです)。 - **署名:** `update.json` は署名つきの封筒(`ffs-update/1`、Ed25519)です。アプリに入っている公開鍵(key_id `ffs-update-2026a`。`dcsmission/updater.py` の `PRODUCTION_KEYS` の 1 か所)で署名を確かめ、通らないもの(改ざん、知らない鍵、別の製品のもの、署名の無い古い `latest.json` の形)は適用しません。中身の版と ZIP の名前が一致し、ZIP の場所が `update.json` と同じフォルダーの `files/` であることも確かめます。署名の検証器 `dcsmission/update_signature.py` は、freedomflight.jp の配信で共通に使うファイルをそのまま写したものです。公開鍵が入っていない版では「この版には更新の署名鍵が入っていません。」と表示し、通信しません。 - **起動時の確認:** 失敗しても何も表示せず、更新のログ(`%LOCALAPPDATA%\DcsMissionStudio\update\update.log`)に記録します。新しい版があるときだけ[更新する][あとで][この版はスキップ]を表示します。スキップした版は、起動時の確認では知らせません(「更新を確認...」では表示します)。 - **確認の画面:** 現在の版、新しい版、ダウンロードの大きさ、この版の内容(12 行まで。切った場合は「…」)を示し、[更新する][あとで]を選びます。新しい版がなければ「最新です(v版)」と表示します。版は `0.4.0a3 < 0.4.0b1 < 0.4.0rc1 < 0.4.0` の順で比べ、読めない版は新しいと見なしません。アルファ版の利用者にも新しいアルファ版を知らせます。 - **取得と検証:** 一時フォルダーに取得し(進捗を表示し、取り消せます)、署名を確かめた `update.json` の大きさと SHA-256 に一致しなければ削除して中止します。SHA-256 のない更新情報は受け付けません。ZIP は、先頭のフォルダー名が `DcsMissionStudio-<版>-win64` であること、危険な名前・リンク・暗号化・重複がないことを確かめてから、インストール先のフォルダーの中の一時フォルダー(`.dcsms-stage-…`)に展開し、中のすべてのファイルが同梱の MANIFEST.json の大きさと SHA-256 に一致し、余分なファイルがないことを確かめます。 - **入れ替え:** 未保存の変更や未適用の入力があれば、通常の終了と同じ確認をします。取り消すと更新もやめます。終了すると、展開した新しい版の `DcsMissionStudio.exe --apply-update` が元のプロセスの終了を待ち、自分の版が想定どおりかを確かめてから、インストール先の MANIFEST.json に載っている旧版のファイルを `.dcsms-old-…` に移し、新しい版を写して起動し直します。途中で失敗したら、写したものを消して旧版を戻し、旧版を起動し直します。結果は `%LOCALAPPDATA%\DcsMissionStudio\update\last-apply.json` に書き、次の起動時に知らせます。 - **後始末と利用者のファイル:** 次の起動時に `.dcsms-stage-…` を消し、`.dcsms-old-…` からは、旧版の MANIFEST.json に載っているファイルだけを消します。利用者がインストール先に置いたファイル(`.miz` など)は動かしません。新しい版と同じ名前の利用者のファイルは `.dcsms-old-…\user-files` に移します。一覧にないファイルは消さずに残し、そのフォルダーを隠しフォルダーでなくします。 - **引き継ぐもの:** 設定と復旧ファイルは `%LOCALAPPDATA%\DcsMissionStudio` にあり、インストール先の外なので、入れ替えの影響を受けません。インストール先のフォルダー名(例: `DcsMissionStudio-0.4.0a3-win64`)は変わりません。 - **入れ替えない場合:** ソースから起動しているとき、配布 ZIP の MANIFEST.json がないフォルダー、書き込めないフォルダーでは、新しい版があることと配布ページだけを示します。 - **試験用の取得元と鍵:** 環境変数 `DCSMISSIONSTUDIO_UPDATE_URL` で、取得元を `http://127.0.0.1:<ポート>/…` か `http://localhost:<ポート>/…` に向けられます(それ以外の値は、https であっても拒否します)。`DCSMISSIONSTUDIO_UPDATE_TEST_KEY=test-<名前>=<公開鍵の base64>` の試験用の鍵は、取得元がこのループバックのときだけ信頼します(key_id は `test-` で始まるものだけ。ループバックの取得元から別の場所への転送には従いません)。`DcsMissionStudio.exe --update-self-test <新しい名前.json>` は、この試験用の取得元のときだけ動く診断で、実際の画面で「更新を確認...」の流れを自動で進めます。 - **配信の作成(dry-run):** `python -B qa/make_update_dist.py --zip --out <新しいフォルダー> --notes-file <説明の文章>` で、`/updates/dcs-mission-studio/manifest.json`(署名する前の manifest。このバイト列がそのまま署名されます)と `files/` を作ります(アプリと同じ検査をしてから大きさと SHA-256 を書きます。署名も公開もしません)。`--release` は実際の配信用で、本番の公開鍵が入っていなければ止まります。そのあとの手順(署名の道具 `ffs-sign.mjs sign` で `update.json` を作り、サーバーには `files/` を先に、`update.json` を最後に置く)は画面に表示するだけで、実行しません。配信の全体版のダウンロードは、公開の配布ページです。 - **ビルドの門:** `build_portable.ps1` は、本番の公開鍵が入っていないと PyInstaller の前で止まります(試験用のビルドだけ `-AllowEmptyUpdateKey`)。入っているときは鍵の key_id と値をビルドの出力に表示します。 ## 対応範囲と制限(dev main 1fbb9ea) - **削除(グループ・ユニット):** 削除後は、グループとユニットの番号を1からの連番に詰め直します(DCS の読込が ipairs で走査するため)。ID で参照される場合(トリガー規則、タスク、ゾーンへのリンク、静的物体、ヘリパッド、selectedTransport など)は削除を拒否し、参照元は自動では変更しません。保存された生成済みのトリガー文字列(trig、result)の中の ID 参照も数えます。型の分かる引数は各名前空間で数え、型の分からない整数は保守的に数えて拒否します(trigrules が無いのに生成済みの文字列がある場合も拒否します)。名前やスクリプトによる参照は、承認が必要です。ゾーン削除は、後続のゾーンのキーを詰め直し、zoneId は変えません。ゾーン ID への参照(トリガー規則、生成済みトリガー文字列の呼び出し、ゾーンへのリンクなど)が残れば拒否します。名前・スクリプトの参照は承認が必要です。 - **ユニット追加:** 最後のユニットを複写し、ME と同じ既定の位置(1体ごとに X 方向 −40 m、Y 方向 +40 m)に置きます。1回で最大16体です。航空機・艦船(callsign・onboard_num・倉庫登録の割当が必要)、ヘリパッド・FARP の静的物体、`DictKey_` の名前のグループは拒否します。 - **ユニット削除:** 1体は残す必要があります。 - **名前変更:** 辞書キー(`DictKey_`)の名前は拒否します。スクリプトや辞書は書き換えません。参照を残したまま承認して変更した場合は、履歴ラベルにその旨を記録します。トリガーゾーンの名前の宣言は、グループ・ユニット名の参照として数えません(第10ラウンド。同梱 2,623 件の計測では、外れた 740 か所はすべてゾーンの宣言で、確認なしで改名できるようになった名前が 327、新たに止まる名前は 0。作業記録)。(履歴: 0.4.0a2 までは、グループ名をゾーン名と同じ名前に変えると、同名のゾーン宣言も参照として数えられ、確認が必要でした。) - **経路表:** 通常の航空機・ヘリコプターの Turning Point だけを対象にします。最大500点です。点3以降で speed_locked が明示的な true でない点は拒否します。経路全体で routeRelativeTOT が true の場合も拒否します。点3以降に 0 以外の ETA か ETA_locked が true の点がある経路(時刻付きの経路)は、保存された各点の ETA と、速度ロックのない点の速度が純正エディターの規則(`dcsmission/eta.py`。ME は ETA を画面の操作のときだけ計算し、保存時には計算しません)と一致し、グループの start_time が点1の ETA と一致する場合だけ編集します。編集すると、ロックのない点の ETA、両側を時刻ロックの点に挟まれた速度ロックのない点の速度(点3以降は速度ロックが必須のため、実際には点1・点2)、点1の時刻が変わる場合の start_time を、同じ履歴で再計算します。保存値と一致しない経路、編集後に規則を満たさない経路、遅延起動でないのにミッション開始より前の時刻になる経路、有限でない値になる経路は拒否し、経路表は理由を表示します。遅延起動の時刻付きの経路は、点1の時刻がロックされていなければ拒否します(ME の検証規則)。(履歴: 0.4.0a2 までは、点3以降の非ゼロの ETA と ETA_locked が true の点を常に拒否し、ETA を再計算しませんでした。)リンク点、離陸・着陸点、対応外のタスクを持つ点も拒否します。スクリプトを含む経路は承認が必要です。ただし、保存された生成 trig・result の Lua が、保存された規則からの再生成と一致する場合は、承認を求めません(生成コードの照合)。実スクリプト(DO SCRIPT、LUA PREDICATE、Script/ScriptFile、initScript、customStartup など)は常に承認が必要です。開いている文書の中では、同じ元ファイルと同じ危険の要約について、もう一度求めません(起動をまたぎません)。点番号の参照は、点の同一性で張り替えます。 - **開始位置の移動:** グループ・全ユニット・経路点1の座標を移動し、編隊のずれは保ちます。経路点2以降、タスク、名前、ETA、start_time は変更しません。ETA は再計算しません。離陸、駐機、着陸、各種リンク(空港、ヘリパッド、滑走路、空母、駐機場、linkUnit)、リンクされたユニットやグループ、空でない route.spans、位置が一致しない場合などは拒否します。機首と psi が両方とも移動前の WP1→WP2 方位に一致する場合だけ、移動後の方位に再設定します。どちらも一致しない場合は変えずに警告し、片方だけ一致する場合は移動を拒否します。 - **数値の編集(点2以降):** 通常の Turning Point だけを対象にします。点2の x / y は機首・psi の扱いの判定に従い、判定が拒否なら保留されます。点1は開始位置の移動だけで変更します。機種性能・地形との照合は未実装です。 - **平行移動・回転:** 既存の対応する形状(通常の経路点と、既知の静的物体の起点点)のみです。道路上の点(On Road / On Railroads)、リンク、未知の座標、対応しない姿勢フィールドは拒否します。回転には各ユニットの heading が必要です。移動量は ±100,000 m まで、回転角は ±360 度までです。`route.spans` は再構成します。タスク内の座標は書き換えません。地表高度・水深の再計算、道路へのスナップは行いません。psi 等の未対応の姿勢フィールドがあると回転を拒否します。障害物との照合は行いません。 - **複製:** 航空機・ヘリコプターは、ME の複製規則に合わせて複製します(タスクを持つものを含みます)。東側の国の callsign と onboard_num は再採番し、onboard_num は常に割り当てます。西側の国の callsign は、呼出名と要素番号を保ったまま、空いている最初の flight 番号へ振り直します(0.4.0a6。ME が選ぶ呼出名と違うことがあります)。Player は Client にし、uncontrolled は偽にします。INUFixPoints・NavTargetPoints と経路点の targets は空にします。西側の国の callsign 表は、呼出名と要素番号を保ったまま、国の中で空いている最初の flight 番号へ振り直します(ME は自分の呼出名の一覧の最初の空きを選ぶため、選ぶ呼出名が違うことがあります。名前の末尾が番号と一致しない表は原文のまま)。BARO 高度は原文のまま複製します(地形高さを読まない既知の差)。地表配置の検査は行いません。駐機欄(parking 系の 4 項目)、追加属性(AddPropAircraft)、データリンク、リンク子(linkChildren、linkChildrenTZone)、DTC、着陸の経路点を持つものは拒否します。道路追従の span、ローカライズ名(DictKey_)、リンクされた静的物体、他のグループ・ユニットを指すタスク、EPLRS・乗車の参照は拒否します。 - **ゾーン:** GUI で、円・四角形の追加、改名(参照の確認つき。承認した場合は名前だけ変わります)、四角形の頂点移動、削除、既存の円の中心・半径と非リンク多角形の平行移動を扱います。頂点の追加・削除は ME の編集ハンドルが4点固定のため拒否します。未知の形状とリンク付きのゾーンは読取専用で、削除も拒否します。不正な形状は編集だけ読取専用で、削除は形状を読まないため拒否しません。座標は DCS 地形座標の m で、入力上限は地形への適合保証ではありません。 - **参照検査:** 読取専用です。グループ・ユニットの宣言 ID と名前、既知のタスク参照を調べます。EPLRS のネットワーク ID はグループ ID として解決しません。未知の ID らしいフィールドやスクリプトは「未確認」と表示します。外部ファイル・辞書・全タスクの完全検証や、自動修復は行いません。最大2,000件、エラー優先です。対象のタスクは、グループとして AttackGroup・FAC_AttackGroup・Follow・Escort・FollowBigFormation・GroundEscort・EngageGroup・FAC_EngageGroup と Cargo 系のタスク、ユニットとして AttackUnit・EngageUnit です。グループ一覧を持つ Embarking・Disembarking(groupsForEmbarking)と ParatroopersDrop(groupsOnBoard)も対象です。 - **詳細フォーム:** 1グループの項目は先頭120項目まで表示・編集します。残りの項目は保持します。 - **日時・静的気象:** 静的気象の既存13項目(日付・時刻・QNH・気温・視程・風)を GUI で編集できます。単位は QNH mmHg、気温 ℃、視程 m、風速 m/s、DCS 保存方向の度です。雲プリセット・旧式の雲層、降水、霧、砂塵、ハロー、地表乱流は、気象パネルから編集できます。動的気象では雲とハローの項目を隠して値を保持します(ME の表示規則)。気温を変えると、その気温で許されなくなった降水は「なし」に戻します(`details.py`)。 - **通信:** 航空機・ヘリコプターの既存 `group.frequency`(MHz)と変調だけです。FM 30–87.975、AM 118–136.975 / 225–399.975 MHz、25 kHz 間隔に制限します。**アプリの対応範囲であり、全機種の無線対応を保証しません**。この変更では、機体プリセット、通信有効フラグ、タスク内のHz値は保持します。 - **無線プリセット:** 航空機・ヘリコプターの各ユニットの既存 `Radio` テーブルの、既存チャンネルの周波数(MHz)だけを変更します。上の対応帯域と 25 kHz 間隔に加え、開いているミッションで同じ機種・同じ無線番号に使われている周波数の範囲の中だけを受け付けます。保存された変調があればその帯域、なければ現在の値の帯域(AM / FM)に限ります。機種ごとの本来の範囲は Lua を実行しないと読めないため確認しません。チャンネルの追加・削除、変調・名称の変更はしません。1ユニット、または同じ機種の全ユニットの変更を1回の履歴として記録します。 - **Lua とZIP:** Lua は実行せず、データ専用のサブセットとして解析します。未知の実行構文は拒否します。上限は、ミッションの文字数 16 MiB、ノード数 1,048,576、テーブル深度 100、ZIP 4,096 項目、展開サイズ 256 MiB です。アーカイブ単位の ZIP64、暗号化、STORED / DEFLATE 以外の方式、前後への付加データ、異常な ZIP 構造は拒否します。メンバーの ZIP64 拡張フィールドは読込時に取り除き、書込時に再生成します。未編集ZIPの圧縮バイト列全体ではなく、各メンバー内容と対応するメタデータを保持します。 文字列のエスケープは Lua 5.1 の規則で解釈します(未知のエスケープは文字そのものとして扱います)。 - **重複するメンバー名:** 内容・メタデータ・フラグが完全に同じ重複だけを受け入れ、先頭の1件を使います。テキストメンバー(mission、dictionary、mapResource、options、warehouses、theatre)の重複と、大文字小文字だけが違う名前は拒否します。 - **ZIP メンバーの名前:** 読み込んだメンバーは、名前の生バイトと UTF-8 フラグ(0x800)を読んだとおりに書き、書いた後の再読込でも確かめます(第10ラウンドの修正)。(履歴: 0.4.0a2 までは「UTF-8 フラグのない名前は、保存時に UTF-8 フラグ付きで書き直します(従来どおり)」と書いていましたが、実際には名前のバイトとフラグが広く書き換わり、資源参照が切れる場合がありました。上の「0.4.0a2 の不具合」。) - **既知の保存上の制限:** 非 BMP の文字を多く含む大規模ミッションでは、履歴の容量を早く使い切ります。POSIX でハードリンクで公開した後に一時ファイルの名前を消せなかった場合、保存は成功として扱い、その名前を `Editor.last_save_leftovers` に記録しますが、画面には表示しません。 - **座標概略図:** 地形の起伏・画像・障害物は表示しません。ME と同じく北(+X)が上、東(+Y)が右です。表示はグループ 1,000、各航路 500 点、画面全体の航路の頂点 40,000、ゾーン 500 までで、超えた分は数えて注記します。DCS のインストール先を設定すると、その地形の Beacons.lua の座標と緯度経度から地形ごとに横メルカトル(WGS84)を当てはめ、町・飛行場(ビーコンの平均位置の目安)・ビーコンを重ねます(手元の 6 地形でビーコンとの差は最大 0.7 m。作業記録)。ビーコンに座標の対がない地形(MarianasWWII)は重ねられません。海岸線・陸上国境は同梱の Natural Earth 1:1000万(パブリックドメイン、無加工)で、細部は目安です。概略図がミッションを変更するのは、グループのドラッグ移動(「移動・回転」の平行移動と同じ処理、移動量は 1 m 単位に丸め)だけです。地形の高さには合わせません。 - **オンライン地図(既定はオフ):** オンにすると、表示している範囲の地図タイルだけを tile.openstreetmap.org から取得し、上の横メルカトルで緯度経度に戻した位置に合わせて、概略図の下へ変形して描きます(ミッション座標の北と地図の北は、地形の中央からの経度差に応じて数度ずれるため)。タイルは届いた順に表示し、ズームの直後はまず半解像度で描いて、まだ届いていないタイルは一つ上の段のタイルを拡大して埋めます。通信は取得の作業ごとに接続を保って再利用します(プロキシの設定があるときは標準の取得方法)。OpenStreetMap 財団のタイル利用方針に沿って、アプリ名と版を名乗る User-Agent で要求し、サーバーのキャッシュ指定(指定がなければ 7 日)まで再利用し、期限切れは条件付き要求で確かめ、先読みや一括取得はせず、同時に 2 件までにし、地図の右下に出典(© OpenStreetMap contributors)を常に表示します。送られるのは表示範囲のタイル番号とこの PC の IP アドレスで、ミッションの内容やファイル名は送りません。タイルは `%LOCALAPPDATA%\DcsMissionStudio\map-tiles` に最大 256 MB まで保存し(同期フォルダーと判定される場所では保存せず、起動中だけ使います)、接続できないときは保存済みのタイルだけを表示します。地図の表示中は、町・海岸線・国境・方眼を省きます。初回にオンにするときに確認し、選択は設定ファイルに保存します。 - **地図データの書き出し:** グループ・静的物体・航路・ゾーン・ブルズアイを、WGS84 の GeoJSON(RFC 7946)または KML 2.2 に書き出します。DCS のインストール先の指定と、その地形の投影が必要です。円のゾーンは72角形にします。海岸線・国境は書き出しません。座標のないもの、形の分からないゾーンは除外し、その数を表示します。書き出しに失敗しても既存のファイルは変わりません。 - **新規作成:** 新規作成は6メンバーの構造候補です。グループ/ユニット配置と倉庫・空港在庫は空です。航空機は追加できません(航空機の配置には開いているミッションにある機種が必要で、新規候補にはグループがないため)。地上・艦船・静的のグループは、作成後に「グループを追加…」で追加できます。日付は手入力、theatre は一覧から選ぶか手入力します。地形の一覧は地形フォルダがあることを示すだけで、国IDの組み合わせや位置と地形・国・空港カタログとの適合は確認しません。地図素材・兵装・スクリプト・添付資料は生成しません。DCS本体との互換性・飛行可能性は未検証です。航空機の配置、参照接続、機種固有設定などは今後の実装です。 - **0.4.0a1 の変更(既存ミッション):** 上の「削除」「ユニット追加」「経路表」「開始位置の移動」「ゾーン」「グループの追加」「日時・気象」の各項目を参照してください。新規作成では、気象の入力範囲を ME の範囲に合わせました(`new_mission.py` の `WEATHER_BOUNDS`)。構造候補の作り方は変えていません。 - **基本設定:** 基本設定は既存フィールドのみです。AI技能と非表示フラグを編集でき、Player/Clientへの変更は扱いません。向きは条件を満たす地上車両・単一静的物体のみ、入力は度・保存はラジアンです。遅延起動は空の経路と整合する既存フラグがある場合、未制御起動は全機AIのコールド開始がある場合に限ります。航空機の高度・速度・向きや離着陸設定をこの画面から変更しません。 - **ブリーフィング:** ブリーフィングは既存の5文章項目を対象に、直接文字列または既存`l10n//dictionary`を編集します。他の項目と共有された辞書キー、欠損/不正な辞書、新規キー/言語/添付の追加は対象外です。添付ファイルの索引(mapResource)は読取専用です。文章変更が複数ZIPメンバーにまたがっても1回のundoで戻ります。文字入力欄のCtrl+Z/Yは入力文字自身の取消です。 - **設定:** インストール先(DCS の読取専用カタログ)と型収集フォルダーのパスを、利用者のアプリデータの `settings.json` に保存します(`%LOCALAPPDATA%\DcsMissionStudio\settings.json`)。保存するのはパスと、更新の設定(起動時の確認のオン・オフ、最後に確認した時刻、スキップした版。初期値のままの項目は書きません。`feat/self-update`)だけで、ミッションや秘密情報は保存しません。保存に失敗した場合は、そのセッションだけ有効です。(履歴: `feat/self-update` の前は「保存するのはパスだけで」でした。)設定の保存先には、復旧のようなクラウド同期の判定を掛けていません。 - **航空機の識別子:** 新規の割当てのコアは `dcsmission/aircraft_ids.py` にあり、複製の経路と規則を共用します。航空機・ヘリの配置も、この割当てを使います。西側の国の呼出名は、ME がこの国の同じ機種に付けた callsign 表(`[1]` の番号と、名前から flight・要素の数字を除いたもの)から取ります(`observed_callnames`)。 - **航空機・ヘリの配置:** 空中開始だけで、経路点は1つです。高度(m)、高度基準(BARO または RADIO)、速度(m/s)を指定し、1グループ 1〜4 機です。機種は開いているミッションにあるものに限り、その機種のグループから燃料・チャフ・フレアと、グループの任務・周波数・変調・通信の設定を写します。写し元は空中開始で余分なデータのないものを優先し、ないときは駐機スタート・データリンク・DTC・最初の経路点のアクションを持つものも使います(それらは写さず、写さなかったことを前提として表示します。アクションを写さないため、AI が交戦しないことがあります)。兵装は空、ユニットの無線プリセットは書きません。BARO の上限は機種によらず 10,000 m、RADIO は 0〜1,200 m です。西側の国は、同じ国・同じ機種の機体に ME が付けた呼出名を使い、空いている最初の flight 番号にします(ME は完全な一覧の最初の空きを選ぶため、別の呼出名になりうる)。その機体がないと拒否します。駐機・滑走路・空母からの開始、Player・Client の技能は拒否します。 - **トリガー(引数・構造の編集、第10ラウンド):** 「引数・構造を編集…」で、既存の条件・アクションの引数のうち、ME の記述子から型と値の範囲が分かるもの(ミッションにあるユニット・グループ・ゾーンの参照先、整数、小数、真偽、フラグ、選択肢)を変更し、条件・アクションとトリガー全体を削除・並べ替えできます。保存された trig が、編集の前も後も規則からの生成結果と完全に一致する(派生と判定される)場合だけ受け付け、trig の該当部分を同じ履歴でその場で書き換えます。次の場合は拒否します: ミッション全体で trig が派生と判定されない(標本 112 件のうち 52 件。作業記録)、引数が保存されていない(既定値の挿入はしない)、資源ファイル(`file`)を持つアクションの削除と、そのようなアクションを含むトリガーの削除(トリガーの削除では a_load_mission を除く。ME は削除時に資源を辞書から外しますが、このツールは外しません)。トリガー全体の移動・削除は、ミッション内のコード(スクリプト、条件式、スクリプトファイルなど)がトリガーの位置を指しうる場合(`mission`、`env.<名前>` 以外の `env` の使い方、`_G`・`_ENV`・getfenv・setfenv・rawget・rawset・debug・package、loadstring などの読み込み関数)と、trig.custom・customStartup に項目がある場合にも拒否します。このコードの検査はヒューリスティックで、実行時に組み立てた名前や他のグローバル経由の参照は見逃しえます。条件・アクション・トリガーの追加はできません。標本 112 件では、引数の編集 256 件と構造の編集 181 件をすべて適用し、1 回の履歴、編集後の派生、保存と再読込、undo でのバイト一致を確かめました(作業記録。全 2,623 件では未計測。画面の試験は合成データのみ)。 - **トリガー(メッセージ文言):** メッセージのアクションが参照する辞書の文言(DEFAULT)を「文言を編集…」で変更でき、トリガーの設定と生成済みの trig は変えません。同じ辞書キーが他の場所(スクリプト、ブリーフィング、生成済みの trig、他のメンバー、他の辞書値)にも現れる場合や、辞書キーを計算で読むスクリプトがある場合は変更できません。保存された trig が規則からの再生成と一致するかの判定は、ME の読込時の旧キーの読み替えと版規則を再現します。ME の保存時の剪定(存在しないユニットや資源を指す規則、末尾の or など)は再現せずに検出し、その影響を受ける文字列は一致と判定しません。(履歴: 0a1abca の時点では、剪定を再現しないため外部で編集された trigrules では判定が甘くなる場合がありました。0.4.0a2 の時点では、トリガーの項目はこの 1 つで、「条件・アクションの構造は表示だけで、編集できません。」で始まっていました。) - **経路点の AI タスク:** 既存の Option の値(ME がそのグループ種別に提供する列挙値・フラグと数値)と、既存エントリの有効/無効だけを、全経路点まとめて1回の履歴で変更します。数値オプションは第10ラウンドからで、DISPERSE_ON_ATTACK(攻撃時の分散、0〜250,000 秒、車両)、OPTION_SET_COLUMN_INTERVAL(隊列間隔、0〜100 m、車両)、AIRCRAFT_INTERCEPT_RANGE(迎撃範囲、0〜100 %、車両・艦船)、DISENGAGE_AND_RTB(損失機数、1〜3、飛行機)を、ME の入力欄の範囲の整数で変更できます。ALT_RESTRICTION_MIN / MAX は、ME が AA_flak のユニットのないグループでは読込時に取り除くため(このツールはユニットの属性を読まず判定できない)、読取専用です。ME がフィート表示で保存した小数などの小数値と、数値オプションに保存された真偽値は表示だけで、変更しません。タスクの追加・削除・並べ替え、目標種別・編隊・兵装種別のオプション、ControlledTask の内側、ME が解決できないエントリは読取専用です。静的グループは対象外です。(履歴: 0.4.0a2 の時点では、数値のオプションも読取専用でした。) - **DCS 検証キット:** 手動の DCS 確認用の入力を作るスクリプトと、保存後の出力を照合するスクリプトです(後述の「検証」を参照)。 ## 検証(dev main 1fbb9ea 時点) 全テストは次で実行します。 ```text python -B -m unittest discover -s tests -v ``` 0.4.0a1 では、次の QA スクリプトも使います。診断レポートには新しい `.json` 名を指定してください。 ```text python -B qa/qa_independent_core.py --project . --report <新しい名前.json> python -B qa/qa_core_fix_regressions.py --project . --report <新しい名前.json> python -B qa/independent_modal_acceptance.py --project . --report <新しい名前.json> ``` 記録(証跡はリポジトリの外の作業フォルダーにあり、ここではファイル名だけを記します)。件数は記録のとおりです。 - dev main `1fbb9ea` の時点: 最後に記録した全体試験は、上の「テスト(0.4.0a6 の候補)」のとおりです。0.4.0a5 の時点: 統合のコミット `1149fc5` の GUI を含む全体試験は 2,470 件、失敗 1、エラー 0、スキップ 3、unraisable 0、tree_clean でした(`merge-1149fc5-suite.json`)。失敗は `test_gui_update` の `test_menus` で、更新の項目が設定メニューの先頭にあると前提していたためです(統合後は、main の設定メニューの末尾に付きます)。試験を `e8a1cee` で直し、`test_gui_update` の 17 件が成功しました。0.4.0a4 の時点の最新の記録は、トリガー・ブリーフィングのタブの `b576e57` で 2,354 件、失敗 0、エラー 0、スキップ 3、unraisable 0(`ui-bt-b576e57-suite.json`、tree_clean 真)です。その前は `6a34bd0` 2,323 件、`0ab6cff` 2,341 件、dev main `63b8376` 2,341 件(上の「テスト」)。地図を主役にしたタブを含む 0.4.0a4 のビルド元 `9bf0118` では 2,372 件、失敗 0、エラー 0、スキップ 3、unraisable 0(`a4-9bf0118-suite.json`、tree_clean 真)。 - 0.4.0a3 の時点の記録: GUI を含む全体試験 2,310 件、失敗 0、エラー 0、スキップ 3、unraisable 0(`round10-merged-suite.json`。git head `9f7d230`、tree_clean 真。そのツリーは dev main `6d72a0d` と同一)。0.4.0a3 のビルド元 `903954d` でも 2,310 件(`a3-903954d-suite.json`)。 - アプリ内の更新(`feat/self-update`、2026-10-25。現在は dev main e8a1cee に統合済み): GUI を除く試験 1,792 件成功、失敗 0、スキップ 3(`selfupdate-nongui-6864ed5.txt`。変更前の 1,743 件に test_updater 49 件を加えたもの)、新しい Tk の試験 test_gui_update 17 件成功(`selfupdate-gui-update-6864ed5.json`。git head `6864ed5`、tree_clean 真)。凍結版 2 本(0.4.0a3 と、試験用に版だけ変えた 0.4.0a4)の梱包監査 passed、自己診断 pass、古い版から新しい版への実地の更新の試験に合格(`field-update-630c477.json`)。GUI を含む全体試験は、このブランチでは実行していません。詳細は[検証結果](QA_RESULTS.md)の「アプリ内の更新」の節にあります。 - 署名つき更新(`feat/signed-updates`、2026-10-25。現在は dev main e8a1cee に統合済み): GUI を除く試験 1,824 件成功、失敗 0、スキップ 3(`nongui-sig-67322e0.txt`。test_updater は 81 件)、test_gui_update 17 件成功、共通の偽配信サーバーとの結合 18 項目合格(`integration-signed.json`)。`67322e0` の凍結版 2 本の梱包監査 passed・自己診断 pass、改ざんした update.json を拒否し、正しい update.json で古い版から新しい版へ入れ替わる実地の試験に合格(`field-update-signed-67322e0.json`)。詳細は[検証結果](QA_RESULTS.md)の「署名つき更新」の節にあります。 - 第10ラウンドの計測(dev main `6d72a0d`。JSON にコミットの記録はなく、コミットは作業記録): 標本 112 件の編集を含む保存の往復 112/112 合格・失敗の項目すべて 0(`round10-postmerge-rt112.json`)、全 2,623 件の無変更保存でメンバー名のバイト・フラグの変化 0、資源参照の解決 44,742→44,742、原本の変化 0(`round10-postmerge-names2623.json`)。 - 0.4.0a2 の時点の記録: 0.4.0a2 のビルド元 `cca840c` で GUI を含む全体試験 2,054 件(`a2-cca840c-suite-display2.json`)。main `0a1abca` と同じツリーで 2,026 件、失敗 0、エラー 0、スキップ 3、unraisable 0(`geo-map-suite-3.json`。git head `810054d`、tree_clean 真)。GUI を除く試験(`tests/test_gui*.py` など Tk を使う試験モジュールを除いたもの)は、pass 6 の文書の更新時に 1,512 件成功、スキップ 3 でした(証跡ファイルなし)。 - 各ラウンドの全体試験(GUI を含む): 第7ラウンド 1,745 件(`round7-merged-suite.json`)、第8ラウンド 1,871 件(`round8-merged-suite.json`)、`647f62b` 1,872 件(`main-647f62b-suite.json`)、第9ラウンド 1,951 件(`round9-merged-suite.json`)、検証キット 26〜28 の 1,956 件(`kit-r78-suite.json` は新規作成ダイアログの試験 1 件が失敗、同じコミットの再実行 `kit-r78-suite-2.json` は成功)、地図レイヤー 1,991 件・2,025 件(`geo-map-suite.json`、`geo-map-suite-2.json`)。`kit-r78-suite.json` の 1 件を除き、失敗 0・エラー 0 です。詳細は[検証結果](QA_RESULTS.md)にあります。 - 第7〜9ラウンドの計測(件数のみ): 削除プレビュー(`round7-delete-preview.json`、標本 112 件)、同梱 2,623 件の読取走査(`corpus-round7-1b6f3ca.json`)、生成コードの照合(`derived-verify-round7-1b6f3ca.json`)、trig の生成文字列の全件比較(`round9-trigver.json`)、AI タスクの全件の変更・保存・再読込(`round9-aitask.json`)。 - 専用サーバーでの読み込み(2026-10-23、dev main `df72332`): 37 ファイルを 1 件ずつ読み込んで 30 秒動かし、すべて合格(`round9-server2-load.json`。1 回目は 31 件目で Tacview のリアルタイム送信の処理が停止し、それを止めた再実行で残りと停止したファイルが合格)。Mission Editor での再保存の確認ではありません。 - 地図レイヤーのビルド: `707c082` のローカルビルドで監査 passed(`geo-packaging-audit.json`)、凍結版の自己診断 pass・10 項目(`geo-frozen-self-test.json`)。 - 0.4.0a1 の最終ビルド(`936b1c0`): GUI を含む全体試験 1,590 件(`final-0.4.0a1-suite.json`)、アーカイブの検証 pass(`final-0.4.0a1-archive-verification.json`)。[リリースノート](RELEASE_NOTES_0.4.0a1.md)を参照してください。 - 以下は f3caf88 の時点までの記録です(履歴)。 - GUI を含む全体試験 1,517 件、失敗 0、スキップ 3(シンボリックリンクの権限)、unraisable 0(`round6-merged-suite.json`。git head `a8bb2fb`、tree_clean 真)。`f3caf88` そのものの GUI を含む試験は未実施です。 - 0.4.0a1 のビルド記録: `build-0.4.0a1-packaging-audit.json`(passed)、`build-0.4.0a1-SBOM.json`(構成要素 16、ネイティブ成果物 21)、`build-0.4.0a1-frozen-self-test.json`(pass、9 項目)。ビルド元のソースでの非 GUI の試験は 1,175 件成功、スキップ 3 です(作業記録。証跡ファイルは未記録)。 - DCS 検証キットの照合(作業記録。証跡ファイルは未記録): 同梱 10 原本から 274 件の出力、期待される変更 498 件、欠落 0、余分 0。 - 履歴: GUI を含む全体試験 1,415 件、失敗 0、スキップ 2、unraisable 0(`round5b-merged-suite.json`。作業記録では 35d8c8c で実行。そのツリーは main 89c6350 の dcsmission/・tests/・qa/ と一致)。同じ件数の `r5b-lead-suite.json` は、ツリーを記録していません。 - b2837b1 そのものの全体試験は、まだ記録がありません。89c6350 から b2837b1 までの差は `dcsmission/spatial.py` の docstring と、`qa/` の報告欄・独立検査の複写だけです。`qa/run_suite.py` は以後、git head と tree_clean を記録します。 - 独立 QA(コア)33 件、失敗 0(`r6-independent-core.json`)。記録した sha256 のうち、lua.py と archive.py は f3caf88 のファイルと一致し、editor.py は f3caf88 のファイルとは一致せず、b2837b1 と 3da759e のファイルと一致します。QA スクリプト自体の sha256 は記録されていません。 - 独立の経路表 GUI 検査 18 件(`r6-independent-route-gui.json`)。QA スクリプトの sha256 は現在の `qa/independent_route_gui.py` と一致します。記録した 88 ファイルは、b2837b1 のファイルと比べると差が `dcsmission/spatial.py`(docstring)の 1 件だけです。f3caf88 のファイルと比べると、88 件のうち 13 件が異なります。`dcsmission/` の 9 件は `__init__.py`、`crud.py`、`editor.py`、`gui.py`、`new_mission_dialog.py`、`spatial.py`、`triggers.py`、`weather_panel.py`、`zone_dialog.py` で、`tests/` の 4 件は `test_crud.py`、`test_gui_r5b_wiring.py`、`test_new_mission_dialog.py`、`test_zones_delete.py` です。88 件はすべて 3da759e のファイルと一致します(作業記録では 3da759e で実行)。合成試験のみで、`native_dcs_gui_verified` は false です。 - モーダル受入 9 件(`r6-modal-acceptance.json`)と ZIP の回帰試験 11 件(`r6-zip-regressions.json`)。ソースの sha256 は記録されていません(作業記録では 89c6350)。 - レイアウト 2 件(`r6-layout.json`)。`native_dcs_verified` は false です。 - 同梱ミッション 2,623 件の読取走査(`corpus-3da759e.json`、probe の git head は b2837b1)。読取と無変更の別名保存だけで、編集後の往復は含みません。 - 統合ブランチの標本 340 件(`round4-postmerge.json`)。ゾーン・配置・気象・トリガーの読取と、undo・再読込の確認。trig の再生成は 340 件、参照索引が complete だったのは 139 件です。 - 生成コードの照合(`derived-verify-before.json`、`derived-verify-after.json`、`derived-spelling-audit.json`)。ゲート通過の機体グループ 235 件のうち、承認が必要なものは 193 件から 122 件に減りました。旧表の 216 件(3 ラウンド時点、`QA_RESULTS.md` の旧表)は履歴です。 - 第3ラウンド統合時の記録(履歴): 全体試験 793 件(`round3-merged-suite.json`)、独立検査 32 件(`round3-independent-core.json`)、経路表 GUI 検査 18 件(`round3-independent-route-gui.json`)、モーダル受入 9 件、ZIP 回帰 11 件。`round3-independent-core.json` と `round3-independent-route-gui.json` が記録する dcsmission/lua.py の sha256(20206fd6…)は現在の(a652b05f…)と一致しません。記録した 60 ファイルのうち 25 件が現在と異なります。 - 1,161 件(`round45-merged-suite.json`。作業記録では 2d25806 で実行。そのツリーは main d2c3ceb と同一)は履歴です。 DCS 本体での読込・再保存は未通過です。`--mission` は飛行用の起動経路であり、編集専用の検証には使いません。公式の Mission Editor の FILE / OPEN、SAVE AS で確認してください(手順は [DCS_VALIDATION.md](DCS_VALIDATION.md))。 手動の DCS 確認に使う検証キットは、次のスクリプトで作り、照合します(`<>` は利用者が置き換えます)。 ```text python -B qa/make_dcs_validation_kit.py --source <原本の .miz> --out <新しいフォルダー> python -B qa/check_dcs_validation_kit.py --kit <フォルダー> --report <新しい名前>.json ``` 生成は原本からバイト単位でコピーし、機能ごとに 1 つだけ編集したミッションを加えます。照合は、利用者が DCS で Save As した `NAME-dcs.miz` を `NAME.miz` と比べる構造の比較です。終了コードは 0(すべて確認)、1(要確認または未完了)、2(入力または内部エラー)です。DCS 本体で読めたことや互換性は、この照合では示しません。 ## ライセンス 独自コードは[MIT](LICENSE)。同梱ランタイムは[依存一覧](DEPENDENCIES.md)、[NOTICE](NOTICE.txt)、`licenses/`の原文、[Windowsバイナリ条件](BINARY-DISTRIBUTION-TERMS.txt)に従います。バイナリ全体をMITと表示しないでください。 DCS本体・DCS の地図・画像・ロゴ・第三者ミッションを同梱していません。概略図の海岸線・陸上国境のために、パブリックドメインの Natural Earth のデータ 2 件を無加工で同梱しています([PROVENANCE.md](PROVENANCE.md)、[依存一覧](DEPENDENCIES.md))。読み込んだミッションや素材の権利は元の権利者に帰属します。独立した非公式ツールであり、DCS開発元の承認・提携を意味しません。 ## 履歴(当時の記述) 以下は 0.3.1 ソース検証候補(2026-10-20)の README を、当時の文言のまま掲載しています。見出しの階層だけを下げています。検証の記録は削除していません。現在の状態は上の各節を参照してください。 ### DCS Mission Studio 0.3.1 — 2026-10-20 レビュー修正版候補 2026-10-07の経路表GUIチェックポイントを基にしたローカル候補です。[包括レビュー](REVIEW_20261020.md)に純正との機能差分と開発順、[検証結果](QA_RESULTS.md)に今回の証跡をまとめています。 今回、日時・気象/航路/基本設定/ゾーンの未適用入力を対象別に保持し、保存・終了前の確認と元値変更時の適用拒否を追加しました。入力は各画面で「変更した項目を適用」するまで保存に含まれません。「このタブの入力を戻す」は、そのタブの別グループ分も含めて入力を破棄します。未適用の航路入力がある対象は、経路表を開く前に適用または破棄してください。フォームのホイール操作とTab追従、Python 3.12.0のコールバック解放も修正しています。 この候補のEXEは作成していません。今回の検証環境はPython 3.12.0 / Tk 8.6.13です。Windowsでは、このフォルダーから `py -3.12 -B -m dcsmission` を実行してください。DCS本体での読込・再保存は未検証です。以下の旧版説明・バイナリ証跡は、記載された版に対応します。 既存のDCSミッションを、原本を残して編集するWindowsネイティブGUIです。0.3.1候補では、空の配置から新規ミッションの構造候補を作るGUIを追加しました。**純正エディターの全機能対応は開発中**です。飛行機能は対象外です。[対応表](FEATURE_MATRIX.md)に実装範囲と未対応、[ロードマップ](IMPLEMENTATION_ROADMAP.md)に全機能への実装順序と受入条件を記録しています。 #### 起動 **0.3.1検証候補はソースのみです。0.3.1のWindows ZIPは未作成です。** 作成時のC:空き約1GiBでは、既定の1GiB予備容量を維持したままビルド用の追加領域を確保できないため、バイナリ作成を保留しました。既存の0.3.0 Windows ZIPは保全していますが、新規作成フローは含みません。 0.3.0のWindows ZIPを使う場合は、任意のフォルダーに展開して`DcsMissionStudio.exe`を起動します。`_internal`と`licenses`などを含むフォルダー全体が必要です。管理者権限・DCS連携設定・ネット接続は不要です。0.3.1の新規作成を試す場合は、次のソース起動を使ってください。 ソースからはPython 3.13とTkがある環境で、プロジェクトのフォルダー内から起動します。 ```text python -m dcsmission ``` #### 操作 「新規 / New」または文字入力欄以外で`Ctrl+N`を押すと、新規作成ダイアログが開きます。地形と日付を選ぶか入力し、開始時刻(時:分)・国ID・ブルズアイ・地図中心・静的気象・5項目の文章を確認して「作成」を選びます。DCS のインストール先を指定していると、地形はインストール済みの一覧から選べ、「DCS の標準の陣営に分ける」で赤・青の国IDがまとめて入り(国名も表示)、ブルズアイと地図中心は「位置」タブの地形の地図をクリックして置けます(飛行場の近くでは飛行場の位置)。日本語/Englishの切替は新規フローに対応し、既存アプリ全体は日本語です。入力エラーではダイアログと入力を保持し、取消では既存文書を変更しません。既存の未保存編集・ブリーフィング下書きがある場合は確認してから文書を交換します。 作成直後は初回保存前として扱い、編集をundoで初期状態に戻しても離脱時に保存を確認します。保存は明示的な「別名保存」のみです。保存先の取消や保存失敗では未保存状態を保持します。操作と入力項目は[新規作成GUI](NEW_MISSION_GUI.md)、データ契約は[新規生成API](NEW_MISSION_API.md)を参照してください。 1. 「ミッションを開く」で`.miz`を選びます。「合成デモ」では同梱素材を使わず操作を試せます。デモはDCS互換確認済みの飛行ミッションではありません。 2. 一覧でCtrl/Shiftを使って複数選択し、MHzまたはkHz、AM/FMを指定して適用します。選択全件を検証してから1回の履歴操作にまとめて反映します。 3. コピー→貼り付け、または複製で新しいグループを作ります。X/Yはコピー先へのオフセット(m)です。新しいIDと名前を割り当てます。 4. 「日時・静的気象」では既存項目を編集できます。「航路の数値」では一覧で1グループを選び、通常のTurning Pointの座標・高度・速度を変更できます。入力は適用まで反映されません。 5. 「基本設定」では1グループを選び、既存のAI技能・表示フラグなどを変更できます。条件を満たす地上ユニットの向きや起動設定だけが編集欄に現れます。 6. 「ゾーン」では既存の円の中心・半径、対応する多角形の位置を変更できます。多角形は全頂点を同じ距離だけ移動し、形を保ちます。 7. 「参照検査」の「参照を検査」で、IDの重複・既知タスクの参照先・未確認の参照を読み取り専用で確認できます。編集後は再検査してください。 8. 「配置・編隊」では一覧の複数選択をまとめて平行移動・回転できます。移動量はm、回転角は度です。対象外のリンクや初期点があれば理由を表示します。 9. 「ブリーフィング」では既存の言語・項目を選んで文章を編集します。「変更した項目を適用」で表示言語の変更を一度に適用します。直接文字列は全言語共通、辞書の文章は言語ごとです。下書きは項目・言語を切り替えても残り、未適用のままでは保存に入りません。 10. 元に戻す/やり直すで操作を取り消せます。「別名保存」で出力し、DCS本体のエディターで内容を確認してください。 `Ctrl+N` 新規、`Ctrl+O` 開く、`Ctrl+Shift+S` 別名保存、`Ctrl+Z/Y` 取消/やり直し。一覧で`Ctrl+A/C/V/D` 全選択/コピー/貼付/複製。文字入力欄では通常の文字編集操作を保ちます。 #### 保護と復旧 原本と同じパス、およびそのハードリンク等への保存は禁止しています。別名出力を上書きする場合は、明示確認後に`出力名.<ランダムID>.bak`を作ります。必要ならアプリを閉じてバックアップを別の`.miz`名へコピーし、DCSで内容を確認してください。 出力と同じフォルダーの一時ファイルへ書き、ZIPとLua構造を再検証してから保存します。失敗時は編集内容・履歴と既存出力を保持します。元の読込元は別名保存後も変わりません。アプリ終了やプロセス強制終了に対する自動セッション復旧は未実装です。履歴は100操作/約64MiBまでで、古い操作から破棄します。 読込中は「読込を取り消す」で結果の採用を取り消せます。処理中の読取自体は安全な区切りまで続きます。保存途中の強制終了は避けてください。変更がある状態で閉じる場合は保存・破棄・取消を選べます。 #### 対応範囲と制限 - 新規作成は6メンバーの構造候補です。グループ/ユニット配置と倉庫・空港在庫は空で、機体やユニットを追加するGUIはありません。日付は手入力、theatre は一覧から選ぶか手入力します。地形の一覧は地形フォルダがあることを示すだけで、国IDの組み合わせや位置と地形・国・空港カタログとの適合は確認しません。地図素材・兵装・スクリプト・添付資料は生成しません。DCS本体との互換性・飛行可能性は未検証です。配置の追加/削除/並替、参照接続、機種固有設定などは今後の実装です。 - 通信編集は航空機/ヘリの既存`group.frequency`(MHz)と変調だけです。FM 30–87.975、AM 118–136.975/225–399.975 MHz、25kHz間隔に制限します。**アプリの対応範囲であり、全機種の無線対応を保証しません**。機体プリセット、通信有効フラグ、タスク内のHz値は保持します。 - 複製は単純な同一ミッション内グループを対象にします。辞書参照の名前、駐機場/離着陸リンク、FARP、スクリプト、非空タスク、未知のID参照がある場合は拒否します。現段階では他グループを参照するタスクを再接続する機能はありません。 - 静的気象のみ、単位はQNH mmHg、気温℃、視程m、風速m/s・DCS保存方向度です。動的気象や雲プリセットは編集しません。 - 航路は通常の航空機/ヘリTurning Pointの既存数値のみです。初期配置、ETA、タスクを自動変更しません。GUIは先頭30ポイントまで編集できます。機種性能・地形との照合は未実装です。 - 基本設定は既存フィールドのみです。AI技能と非表示フラグを編集でき、Player/Clientへの変更は扱いません。向きは条件を満たす地上車両・単一静的物体のみ、入力は度・保存はラジアンです。遅延起動は空の経路と整合する既存フラグがある場合、未制御起動は全機AIのコールド開始がある場合に限ります。航空機の高度・速度・向きや離着陸設定をこの画面から変更しません。 - ゾーンは既存の非リンク形状のみです。円の中心・半径、多角形の平行移動に対応し、追加・削除・改名・ID変更・頂点の個別編集は未実装です。未知形状、リンク付き、不正な形状は読取専用です。座標はDCS地形座標のmで、入力上限は地形への適合保証ではありません。 - 読取専用の「参照検査」は、グループ/ユニットの宣言ID・名前と、既知の攻撃/追従/護衛等のタスク参照を調べます。EPLRSのネットワークIDをグループIDとして解決せず、未知のIDらしいフィールドやスクリプトは未確認と表示します。最大2,000件、エラー優先です。外部ファイル・辞書・全タスク・名前参照・機種適合の完全検証、自動修復、複製の許可範囲拡大は行いません。 - 座標概略図には地形・空港・障害物を表示しません。最大1,000グループ/各500経路点の概略表示です。 - 配置・編隊は既存のグループ・全ユニット・全経路点の平面座標を一括変更します。通常Turning Pointと整合する初期点、連続する配列、曖昧さのない選択IDが必要です。リンク先の物体、駐機/離着陸、未知の座標・タスク等は拒否します。回転は既存headingが必要で、psi等の未対応姿勢フィールドがあると拒否します。地表高度の再計算や障害物照合は行いません。数値精度は[配置API](SPATIAL_API.md)を参照してください。 - ブリーフィングは既存の5文章項目を対象に、直接文字列または既存`l10n//dictionary`を編集します。他の項目と共有された辞書キー、欠損/不正な辞書、新規キー/言語/添付の追加は対象外です。資料索引は読取専用です。文章変更が複数ZIPメンバーにまたがっても1回のundoで戻ります。文字入力欄のCtrl+Z/Yは入力文字自身の取消です。 - Luaを実行せず、データ専用サブセットとして解析します。未知の実行構文は拒否します。上限はmission 16MiB、テーブル深度100、250,000ノード、ZIP 4,096項目、物理/合計展開サイズ256MiBです。 - ZIP64全体、暗号化、STORED/DEFLATE以外、前後への付加データ、異常なZIP構造等は拒否します。未編集ZIPの圧縮バイト列全体ではなく、各メンバー内容と対応するメタデータを保持します。 #### 検証・ビルド [検証結果](QA_RESULTS.md)と[DCS本体での確認手順](DCS_VALIDATION.md)を参照してください。各版の全テスト数とWindows権限によるスキップ、独立GUI検査、配布物の検査結果を記録しています。許可済み実ミッション3件のコピーでは、辞書ブリーフィング変更・undo/redo・再読込を確認し、編集対象外メンバーと入力ファイルは不変でした。これらの実データは配布していません。 **既存ミッションの編集出力と新規構造候補は、どちらもDCS本体での読込・再保存が未検証**です。この実行環境ではDCSの画面操作に必要な`node_repl`/ComputerUseのUIツールが利用できず、本体検証ゲートを通せていません。公式GUIのMISSION EDITOR → FILE/OPEN → SAVE ASが確認経路です。`--mission`は飛行用で、編集専用の検証CLIとして使いません。詳細な根拠は[ロードマップの読込経路](IMPLEMENTATION_ROADMAP.md#dcs-起動読込経路の調査結果)にあります。次は型別の参照接続、追加/削除などのCRUD、機種・地形カタログと配置を伴う新規作成へ進めます。 ```text python -B -m unittest discover -s tests -v python -B qa/qa_independent_core.py --project . --report .local/core-result.json python -B qa/qa_core_fix_regressions.py --project . --report .local/zip-result.json python -B -m dcsmission --self-test .local/source-smoke.json ``` 診断レポートには新しい`.json`名を指定してください。同名ファイルは上書きしません。 以下は十分な空き容量を確保した後のWindowsビルド手順で、0.3.1では未実施です。Python 3.13.5とPyInstaller 6.22.2が既にある専用環境で実行します。スクリプトは依存を導入・更新せず、キャッシュと出力をプロジェクト内に置きます。 ```powershell .\build_portable.ps1 -BuildPython 'path\to\build-environment\python.exe' -BuildTag v031-candidate-local .\dist\v031-candidate-local\DcsMissionStudio\DcsMissionStudio.exe --self-test '.local\binary-smoke-v031.json' ``` `BuildTag`は省略可能で、省略時は一意なタグを生成します。出力は`dist//DcsMissionStudio/`です。同じタグのビルドが既にあれば停止し、過去の成果物を残します。タグを変えて再ビルドしてください。スクリプトはPythonや依存パッケージを自動導入しません。 ビルド環境の準備が必要な場合も、他プロジェクトの共有環境を更新しないでください。ビルド後に依存・ライセンスと診断結果を確認してから配布用ZIPを作ります。公開やGitHubアップロードは行っていません。