WSN(XML)シナリオへの新仕様追加の問題と方針について

Issue #184 new
k4nagatsuki repo owner created an issue

仕様の「衝突」の可能性について

CardWirthPyはWSNアーカイブ(実体はZIPで中身はXMLと素材)という独自形式のシナリオを再生できます(元々はそれのみを再生でき、今でも他形式を内部的にXMLへ変換しています)。

WSN形式のシナリオに独自機能を実装する事は容易なのですが、これまで実行してきませんでした(reboot前の背景変更関係の機能を除く)。その理由は、他エンジンで実装された機能と仕様が「衝突」する可能性があるからです。

例えば、「ラウンド終了イベント」を実装する事を考えます。現在、ラウンド終了時の処理としては、時間を経過させて毒のダメージを与え、各種状態の残り時間を減らす……といったものがあります。それらの前後もしくは間のどこでラウンド終了イベントを実施するべきでしょうか?

仮に、WSN形式が時間経過処理「前」に実行される形でラウンド終了イベントを定義したとしましょう。ここで、他エンジンが時間経過処理「後」に実行する形で実装すると、2種類の、よく似ているが微妙に違うラウンド終了イベントが存在する事になり、これらを統合しようとした時、仕様が汚くなるのみならず、シナリオ作者を戸惑わせてしまいます。これが仕様の衝突です。

このように、他形式との統合や変換を考える場合、シナリオデータの仕様の追加は安々と判断できる事ではありません。ただし、他と仕様が食い違いようがないような追加機能も考える事ができます。例えば「麻痺時にも動ける召喚獣」のような仕様を考える時、カードデータにそうしたフラグを設ける以外の実装はほとんど考えられないと思われます。

衝突する可能性が高い機能としては、例えば次のようなものが考えられます。

  • 計算でき、文字列も数値も扱える変数
  • パッケージの引数
  • ループや分岐後の合流といった制御構造の追加
  • PCや使用中カードのキーコード・死亡イベント
  • テキスト内の変数出力の強化
  • その他色々

まず衝突しない、もしくは衝突状態になっても容易に解消できるであろう機能としては、次のようなものが考えられます。

  • 手札や召喚獣をコピーではなく参照する
  • カード画像を1枚のカード上で重ねて表示する
  • アクションカードを引かない敵
  • 音声のフェードイン・フェードアウト
  • キーコードやステップの点数の制限解除
  • その他様々

また、すでに他形式で実装済みの機能についても、ほとんど衝突の恐れなく実装できます。すでに実装がある以上、仕様が極端に食い違う事は考えづらいからです。

シナリオ機能追加の方針

  1. まず、0.12.2がリリースされるまでは、シナリオの機能追加は行いません。
  2. その後は、「衝突」しない機能を優先して徐々に追加しますが、衝突する可能性のある機能もそれが著しく有用であれば追加を検討します。
  3. もし他形式と「衝突」が発生してしまったら、仕様が汚くなっても内部的な変換を試みます(ただし元々その形式からの変換が可能な場合のみ)。
  4. WSN形式のみを変更し、クラシックなシナリオには手を付けません。
  5. 提案のIssueを立てるのは、いつでもOKです。いかなる機能も、どのような仕様にするべきか、実際の衝突可能性がどれくらいか、Issueで議論を経るべきです。

これはコミッタとしての私が独断的に考えた事です。ご意見により変更する可能性が高いです。

上に書いた事々について考えがある方は伝えていただければ幸いです。

WSN形式から他形式への変換について

WSN形式固有の機能の使用箇所を容易に取り除くか作り替えて他形式への変換を試みる事ができるよう、エディタ側で工夫するべきです。対象エンジンバージョンによって警告を出す等するとよいでしょう。

宿については、新機能の入ったカードを含む宿でも逆変換できる必要があります。Issue #166の対応で非対応機能に例外を投げる機構を設けたので、それを利用すれば容易に対応できるはずです。

エディタ側の対応について

今のところCWXEditorで対応するしかありません。同時進行で作業する必要があります。

Comments (6)

  1. tachi gigas

    お疲れ様です。

    シナリオ機能の拡張追加はクラシックエンジン等との互換性を失う話になるので、率直な話、正直怖い事だと思います。それにより正規エンジンでプレイできなくなるシナリオが出来てしまう事は個人的には色々な齟齬を作ってしまうという印象を持っています。

    しかし、これはWSN形式に限った話でありますので、k4nagatsukiさんの自由にされていいと思いますし、そうあるべきでしょう。もちろんIssueにて広く意見を募集されている事も良い事だと思います。が、僕には新機能のアイディアもあまり無いですし、口出しする予定はありません。

    本家様1.29リリースより前の話ながら、Py固有機能が既に実装されている以上、僕の杞憂は問題ないかも知れません。

  2. k4nagatsuki reporter

    ご意見ありがとうございます。正直言って私も怖いです。新機能を作るのは簡単ですが、互換性の問題が生じます。互換性が失われて誰が損をするかといえばユーザです。ユーザに不利益を与えるような事はできる限り避けたいです。

    しかし、CardWirthは、たまたま10年も変化が無い物ではありましたが、もっと長いスパンで見れば、強化され、機能を充実させられてしかるべきものだとも思っています。やりたいと思った事が、シナリオ機能の制約でいつまでもやれないというのも、またユーザの不利益だという思いもあります。

    仮にいくつかのシナリオの規格が別々に立つとしても、将来的に他形式と相互運用できれば、最初に挙げた不利益は消滅し、利益のみを得られるようになるかもしれません。が、そうなるという保証もありません。

    いずれにせよ慎重さが必要です。仮に上に挙げた事を実践するとしても、実際に私が提案等を行うのは当分先になると思います。

  3. Num_400

    お疲れ様です。

    この問題について、少し発想を逆転して考えてみました。 将来の仕様衝突が問題でしたら、衝突の可能性が低い界隈でWSN仕様を実装してはどうでしょうか? 例えばSFバリアント向けエンジンという形で新機能を実装してみるのです。

    ご存じのとおり各種バリアントのサポートは事実上打ち切られています。 現状のままなら、特定のバリアントだけに新機能を提供しても、他のエンジンと仕様衝突する可能性は低いと考えられます。

    また公式エンジンと互換性が無くなるという課題についても、 正規ではないバリアントであれば、ユーザーが別物と捉えてくれる可能性は高いと思います。

    上手くやることが出来ればバリアントが再活性化し、Cardwirthの遊び方を増やすこともできるのではないでしょうか。

  4. k4nagatsuki reporter

    ありがとうございます。ご意見をいただけると助かると共に大いに励みになります。

    いわゆるファンタジーⅠ型とその他バリアントについてですが、これらはそれぞれ外見上かなり異なるものではありますが、実はシナリオの仕様としては全く同じものです。例えばSFバリアントにあるイベントコンテントが学園バリアントには無い、というような事はありません。キャラクターの特性名や能力値に違いのあるものもありますが、これは内部的にはクーポンで処理されているので、シナリオのデータ構造とはまた別のレイヤの話になってきます。

    そのため、「特定のバリアントだけに新機能を提供」というのは、「バリアント(スキン)ごとにシナリオ構造を個別化する」という話に繋がってしまい、却って難しい互換性問題になる事をご理解いただけると嬉しいです。

    それとは別に、Num_400さんの提案によって提起される課題があって、それは「既存のバリアントの後継としてCWPyを使用するような働きかけを行うべきか?」というものです。

    現在、CWPyのスキンは、Classicを除けば、既存のバリアントエンジンを元にユーザが自動生成するという形でしか手に入りません。しかし、これは望ましい状態ではないと私は考えています。私の考える理想的な状態は、シナリオのように、ユーザが作成したスキンを配布して、それをダウンロードした人が自由にインストールできるようになっていたり、あるいはCWPy本体にいくつかのスキンを同梱してCWPyをダウンロードした人がすぐに使用できるようになっていたりする、というものです。

    「バリアントの再活性化」は、そのような状態によってもたらされるのがよいと私は考えています。で、問題は、例えば既存のバリアントの開発者に「今のバリアントエンジンをCWPyのスキンに変換して本体に同梱したり自分で配布したりしませんか?」と働きかけるべきかということです。

    現状のCWPyは結構難しい立場にあるので、なかなかそうした行動に出る踏ん切りがつきませんし、言われた側も困ってしまうかもしれません。

    そして、それはデータ構造の件とは別の話になってしまうので、これについてはそのうち別のIssueを立てた方がよさそうですね。

  5. Num_400

    ご返信ありがとうございます。少し誤解があったようなので返信させて頂きます。

    「バリアント(スキン)ごとにシナリオ構造を個別化する」と何やらややこしい話をされていますが、 自分の中では「Py」から「Reboot」が作られたように、「Reboot」から「バリアント向けエンジン」のブランチを作成すればどうだろう、と提案していました。 ガワだけでなく中身も変えてニッチな界隈で活躍させてみたらどうだろうという程度の考えです。

    ただブランチを作成してしまうと、管理が二本立てになってしまうので、それはそれで面倒だよなぁと後になって思いましたね。

  6. k4nagatsuki reporter

    なるほど、メインストリームで行わずにブランチを切って実施する感じの提案だったのですね。

    しかしやはり最後には統合の問題がやってくるので上手くやらないと後が大変そうです。いずれにせよ実装する機能はよく検討しないといけませんね。ともあれ、ご提案ありがとうございます。

  7. Log in to comment