開発資料/コンパニオン改造手引/GG_CJE解体新書

はじめに Edit

このチュートリアルはGG Companion Japnese Edition v.1.1(以下GGに略)をもとに、その構造を読み解くことでCS(コンストラクションセット)使いとしてのスキルアップを図るのがその目的です。また、初めに断っておくのは、これは初心者を対象にしたチュートリアルではないということです。少なくともTESCSWiki(またはCS日本語ヘルプ)のGetting StartおよびスクリプトのチュートリアルであるMy Second Scriptを流し読みでもいいですからしておき、CSの基本的なシステムを理解しておいてください。CSWikiは一度読んでみたが、あまりわからない。でもCSの構造をなんとなく理解はしたという人にとって、このチュートリアルは役にたつだろうと思われます。
 
本チュートリアルをより理解するための下準備として、GGをゲームに導入して、そのコンパニオンとしての機能を実際に確認してみてください。そしてこのチュートリアルを読み進めていくにあたり、TESCSを起動して、説明をしている箇所をそれで確認しながら読んでいくとよいかと思います。
 
それではチュートリアルをはじめましょう。

オブジェクトの名前について Edit

まずはMODを作る際の注意を少ししたいと思います。CSを開いて、メインツールバーのFile/Dataで出るDataウィンドウのDetails...ボタンで変更点を確認すればわかりますが、GGの場合、変更している様々なオブジェクト(スクリプトやクエストなども含む)のID名には、GG〜やらGG_Valeriaという文字列が名前の先頭に入っています。
 

#ref(): File not found: "GG_T_001.jpg" at page "開発資料/コンパニオン改造手引/GG_CJE解体新書"

 
こうして変更するオブジェクトの名前を統一しておくことは、自分自身にとっても後で作業がしやすくなるので、見習うべきかと思います。
 
ちなみに、別々のMOD同士の中で、ID名が偶然にも同じになってしまうと、コンフリクト(衝突)して、MOD自体が正常に動作しない場合があるので、汎用的な名前を付けるのは避けた方が無難です。またID名の先頭に、数字の「01〜」などを付けると、リストの一番初めにその項目を持ってくることができ、MODを製作する際には便利です。これを踏まえると、「01GG〜」のような名前にしていくと、作りやすくなるかもしれません。と、書きましたが、Sさんの情報によると数字が入っているIDはスクリプトで上手く認識されない場合があるとのことなので、どうしてもリストの先頭にそのIDをもってきたい場合には「AAGG」などの名前にすべきかもしれません。
 
それではGGを導入するとどのような変更が行われるのか、実際にゲームで反映されている部分をピックアップして見てみましょう。
 

MapMarkerについて Edit

GGを入れてゲームをスタートすると、MAP画面にValeria’s Campという場所が新たに登録されます。これはObject WindowのWorldObject/Static/MapMarkerをその目的地に配置したことにより表示されるものです。
 

GG_T_002.jpg

 
上のピクチャーはそのMapMarkerのプロパティです。「Visible(視認可能)」と「Can Travel To(ファストトラベル可能)」にチェックをいれることで、ゲームをスタートした時点でMAP上への登録とそこへのファストトラベルが可能になります。
 
それでは実際にValeriaに会いに行って見ることにします。ファストトラベルを使用してValeriaのもとまで行くと、彼女はずっと立ちっぱなしで、どうやらそこから一歩も動くことはないようです。
 

NPCの動作について Edit

演出としてコンパニオンが仲間になる以前には、他のNPCと同様、タイムスケジュールを設定して、自然な生活をさせるというのもいいですが、ユーザーはどこにいるか知れないコンパニオンを探すのに、苛立ちを覚えるかもしれません(とはいえクエストを用意して、彼女がいる場所をマーカーに追尾・表示させることで、それを回避させることは可能です)。GGの場合、作者がそれを意図したのでしょうが、Brumaのキャンプで彼女は何もせずボーっと立っています。これはAI設定において、彼女のAIパッケージが動作していないことを意味しています。
 

AIパッケージについて Edit

オリジナルのNPCが日々生活をしているように振舞えるのは、AIパッケージのおかげです。そしてMODの中で新しいNPCを作成しようと思えば、当然AI設定は活用すべきでしょう。そうしないと一日中ボーっと立っているだけの無気力なNPCが出来上がってしまいます。
 
ただ、日常生活だけを送るNPCとは異なり、コンパニオンはプレイヤーキャラに着いて行き、一緒に戦ってくれなくてはなりません。とすれば、コンパニオンのAI設定は特定の条件で限定的に用いていくことになるかと思います。実際にValeriaにはどのようなAI設定がなされているのか見ていくことにしましょう。
 

#ref(): File not found: "GG_T_003.jpg" at page "開発資料/コンパニオン改造手引/GG_CJE解体新書"

 
リストを見てみると、どうやらGG〜から始まる新しく作成した9つのパッケージを持たされているようです。ちなみに新しくPackageを作成する場合は、メインツールバーのCharacter/Packages...で作成してから、各NPCのAI設定のリストにそれらをドロップする必要があります。さて、それでは上から2番目の項目である「GGValWander」を開いてみてください。
 

GG_T_004.jpg

 
その項目をダブルクリックして開いて、ScheduleタブのDuration(持続時間)を見ると、どうやら「GGValWander」は持続時間が2時間に設定されているWanderパッケージ(あたりを適当にうろつくパッケージ)のようです。これはどんな時に使用されるものなのか、Conditionsタブを開いて見てみることにしましょう。
 

Conditionsについて Edit

Conditionとは「条件」という意味ですが、これはMODを作成していく上で非常に重要なものです。ある一定の条件を満たすと、何かが起こるという方法をとることで、ゲームが管理しやすくなるからです。少し詳しく説明していきましょう。
 
スクリプト初心者の方はTES4CSHLPのScript/Conditionを参照しながら読み進めていくことをお奨めします。
 
さて条件設定ですが、この「GGValWander」の場合ならば、GGの作者は「プレイヤーと一緒にいる間は、勝手にうろうろされては迷惑だが、コンパニオンが自分の家にいる時には、うろうろしてほしい」という意図の下、条件を設定しています。つまりピクチャーにある条件のリストは「どこか自分の家にいる場合」を設定しているものなのです。
 

GG_T_004.jpg

 
Conditionsタブのリスト項目、上から4番目の項目を見てください。条件を設定するにあたり、ウィンドウの下にある5つの項目を設定していきます。最初に日本語でここでの条件設定がどうなっているのかを言ってしまうと、
「今コンパニオンがいるセル(場所)の情報を得て、それがSkingardHouseforSaleという名のセルだったら条件を満たす」
ようにここでは設定されています。
「Condition Function」とは条件を設定する際に用いる関数のことです。ここでいう関数とは数学のアレではなく、TESでのみ使われる命令言語とでも思えば大丈夫です。なお条件設定で使用される関数は通常のスクリプトで用いられるものと同じと考えてよいです。逆に言うと、条件設定を正しく設定できるようになるためには、スクリプトの知識が必要になるということでもあります。
 
さて、ここでセットされた「GetInCell」とは「そのセルの情報を教えろ」という関数です。この命令が出されると、現在そのコンパニオンがいる場所の情報が得られます。
そして「Function Parameters」でその得られたセルの情報と比較するセルを設定します。
「Comparison」は比較という意味で、そこには「==」が入っていますが、これはイコールと同じ意味です。
 
それでは次の設定項目であるValueが「1」とはどういうことなのでしょうか?
これは「GetInCell」という関数がどんな機能を持っているかを調べればおのずと意味がわかります。通常GetInCellがスクリプトで使用される場合、「GetInCell SkingardHouseforSale」のような形で用いられ、もしそのコンパニオンがいる場所がSkingardHouseforSaleであった場合には、GetInCellは数字の「1」を返すことになり、それ以外の場所にいる場合には「0」を返すことになります。
この条件設定タブウィンドウで行う設定をスクリプトで記述するならば、

if GetInCell SkingardHouseforSale == 1
  →そのコンパニオンをうろうろさせる

 
ということになります。
もしその場所がSkingardHouseforSaleならば「1 == 1」なのですから条件は合致して、以下の行の「そのコンパニオンをうろうろさせる」行動をさせるわけです。そしてもしその場所がSkingardHouseforSaleでないならば「0 == 1」で条件は一致しませんから、「そのコンパニオンをうろうろさせる」ことはしないわけです。
 
それでは話を条件設定タブに戻します。タブの右下にある「OR」にチェックを入れると、文字通り「または」として条件をつなげることができます。今回の条件設定ではコンパニオンがいずれかの都市の家にいる場合を条件としたいので、Skingardの家「または」、Chorrolの家「または」、Brumaの家「または」、〜と全ての都市の家をORでつなげて条件のセットをしています。
 
これで条件設定を一通り見ましたが、実は「Condition Function」でセットする関数によってそれらの設定の仕方は随分変わります。
 
例えばリストの2番目の項目は「GetRandum Percent」という関数をセットしていますが、これは「Function Parameters」を設定する必要がありません。そしてこの機能自体は、0〜99までの数字の中からランダムに数値を取り出すものであり、そのValue値の設定を見れば80パーセントの確率でそれが起こるよう条件付けられているのがわかります。
 
またリストの1番目の「GetScriptVariable」は対象となっているオブジェクトに添付されているスクリプトが宣言した変数の数値を条件として設定することができます。
こういった変数はそれだけを見てもどんな条件を設定しているのかわかりにくいものです。ここでは「GGValのbDoWait」という変数がその対象になっているのですが、これはValeria自身に添付されているスクリプトの中で宣言されているもので、実際にはTOPIC(会話)の際、プレイヤーがその場にコンパニオンを留まらせる時に使用する変数になっています。その場にコンパニオンを留まらせるという指示は、MODなどで新しく導入した家や、各都市に所有する自分の家以外の家にコンパニオンを置いておく場合に用いられるものです。つまり1番目の「GetScriptVariable」は、自分の家以外の家でうろうろするための条件として設定してあったというわけです。
 
他のパッケージもこのような要領で設定してありますので、いろいろなパッケージを覗いてみて、条件としてどういった関数がどのように使用されているのか見てみると勉強になると思います。そして全てのパッケージを見たならばわかると思いますが、Valeriaがプレイヤーキャラの仲間になるまでの状態は、どのAIパッケージの条件にもあてはまりません。したがって彼女は仲間になるまでキャンプでボーっと立っているわけです。
 

クエストの概略について Edit

さて彼女に話しかければ当然会話が返ってくるわけですが、会話部分については、CSWikiを見てもそれらのコンテンツが充実していない印象があるので、少し概略から先に説明してみようかと思います。
まずTESで用いられる会話はクエスト単位で制御されています。
ここでいうクエストとはメインツールバーの「Q」のボタンを押すと開かれるQUESTウィンドウにリストされているものです。
 

GG_T_005.jpg

 
この場所はTESのデーターベースと言ってよい場所で、ゲーム上で使用される「ジェフリーにネックレスを届けろクエスト」などでいう「クエスト」とNPCなどが話す全ての会話がここで管理されています。そして一言に会話といっても、QUESTウィンドウでそれはTopics・Conversation・Combat・Persuation・Detection・Service・Miscと会話の状況に応じて7つに分類されています。
また会話の編集作業は、個々のNPCのプロパティのDialogueボタンから開かれるDialogueウィンドウでも可能です。
 

GG_T_006.jpg

 
しかし、このウィンドウでは新しいTopicを追加できない仕様なので、会話を編集する際はQUESTウィンドウ上で行ったほうがいいかもしれません。会話はこのように2つの場所からアクセスが可能ですし、細かな分類もしてあってCSを使い始めの時は戸惑うかと思います。しかし、まずクエストがあり、その中に会話が入っており、さらにその会話は状況に応じて7つに分類されているということだけ覚えていれば、オリジナルの会話を参考にしようとする時や、自分で会話を作成しようとする際の取っ掛かりになると思います。
 
たとえばネズミ退治のクエストと、それに関連するNPCを2人新しく作成したならば、「ねずみ退治クエスト」というクエストの中で、その2人のNPCの会話をすべてまとめてしまうのが良いと思います。そして会話の中でも、「ネズミが地下の穀物を食い荒らして困っているんだ」などの通常会話はTopicsタブに分類し、「このネズミ野郎!犬の餌にしてやる」などの戦闘の際の掛け声は、Combatタブ内にそれぞれ作成していくということになります。
 

GGのクエストについて Edit

それではGGのクエストはどうなっているのでしょうか?
ツールバーのQUESTSボタンでQUESTウィンドウを出して調べると、GGValeria〜という名のクエストが15個見つかりました。どうやらその中の「GGValeriaQuest」がゲーム上でValeriaが実際に会話をする部分を司っているようです。その他のクエストはValeriaのコンパニオンとしての機能を司るものが大半のようです。
 
ここで気をつけるのは、クエストは会話のデーターベースとしての使用方法や、クエスト履歴としての使用方法以外にも使い道があるということです。(ちなみにここでいうクエスト履歴とはゲーム内のクエスト関連の部分(アクティベートクエスト・コンプリートクエストなど)にクエストの進行度を文章で表示させることです。)
 
GGValeriaDoOnceというクエストを見てください。
 

GG_T_005.jpg

 
ここには会話も書かれていませんし、クエスト履歴として機能しているわけでもありません。ただGGValeriaDoOnceScriptというものがスクリプトとして添付されているだけです。これはクエストスクリプトというスクリプトタイプを使うためだけに用意されたクエストです。
 

スクリプトの添付場所について Edit

もともとスクリプトはオブジェクトに添付されることでその機能を果たします。Valeriaに何かをやらせたいのならば、NPCであるValeria自身にその命令(例えば武器を修理しろなどの命令)をスクリプトとして書いて添付してやればいいわけです。しかしGGはクエストスクリプトという形でクエストにValeriaのコンパニオン機能を添付しています。
 
もう少し言うと、Valeria自身にもスクリプトが添付されていますが、他のクエストも用意してそこにもスクリプトを添付しています。両者のスクリプトはValeriaコンパニオンとしての機能という意味で全く同じです。ただしそれらのスクリプトは2つの違いがあります。
 
1つはその実行される頻度の問題です。
NPCに貼られたスクリプトはNPCのAIが実行される頻度と同じで、プレイヤーキャラが近くに居る場合は高い頻度で実行され、遠くなれば低い頻度で実行されます。それに対しクエストに貼られたクエストスクリプトはそのクエストがアクティブになっている間はデフォルトで5秒ごとに実行されています。
 
2つ目は使用できるスクリプトの違いです。
NPCに貼られたスクリプトにはリファレンススクリプト(参照スクリプト)が使用できます。これは添付されているオブジェクトがその対象となるので、わざわざ対象を指定する必要がないということです。それに対してクエストスクリプトはノン・リファレンススクリプト(非参照スクリプト)で、その命令を実行する対象を指定する必要があります。
 
これらスクリプトの属性を考えてGGはスクリプトを添付する場所を分けたのでしょうか?
私はGGの場合、そんなに属性のことは考えず、主にそのGGに使われる命令の種類によって分割したのだと思います。
 
実際、2つ目のリファレンススクリプトか、ノンリファレンススクリプトかは「スクリプトを書く手間」の問題であるので、どちらだからその機能が制限を受けるという類のものではありません。
 
(余談になりますが、GGの場合ノンリファレンススクリプトを使用して、かつ変数を多く参照項目として指定して記述してしまっているので、コンパニオンを新しく作成しようとすると、その指定した場所を全て書き換えていく必要があるため大変手間がかかります。何かを参照する変数は、リファレンススクリプトとしてValeria自身に添付されたスクリプトに書き込んでくれていれば、簡単に複数のコンパニオンを作れるようになっていただろうということは付記しておきます)
 
また実行頻度の問題もコンパニオンはもともとプレイキャラクターの近くにいるのが常態のためあまり問題になりません。GGの場合プレイヤーと離れて指定された宿屋や家に行く場合があるのですが、それはスクリプトではなくAIの仕事なので問題になりません。つまりGGの機能をみるとあえてそれらスクリプトの属性を踏まえて命令を割り振る必要性は薄いのです。したがってGGは、Valeria自身に添付されたスクリプトが長くなるのを嫌ってスクリプトを分割したと考えるのが自然でしょう。
 
ただこれから新しいスクリプトを作成しようとする人は、スクリプトが実行される頻度については覚えておいた方が良いと思います。プレイヤーキャラクターが近くに居ない場合でもスクリプトを高い頻度で動かしたい場合は、クエストスクリプトを用いた方が良いでしょう。ただし、その高い頻度で動かすスクリプトが複雑で長いものであると、パソコンのマシンパワーを多く消費するということを忘れないでください。そしてそのスクリプトの役目が終わったら、クエストを「StopQuest」関数で止めるのを確実にするべきでしょう。そうでなければいつまでも、5秒間に一度、そのスクリプトを実行しつづけてマシンパワーを浪費し続けてしまいます。
 

Valeriaとの会話 Edit

さてこれからは実際にValeriaと会話することにより彼女に命令させることができる機能を見て行きたいと思います。Valeriaの会話はGGValeriaQuestのTopicsタブにまとめられています。実際にCSで開いてみてください。
 
初めてValeriaと話すと彼女はオリジナルのGreetingを使った挨拶をします。そして彼女をコンパニオンとするかどうかの選択肢が出てくるわけですが、これらの会話作成の方法はCSWiki(日本語ヘルプの場合)のGetting Started / Quest Tutorialを参照してください。
 

Result Scriptについて Edit

それでは実際にValeriaの会話の一部を見て見ましょう。
「Editar ID」リストから「GGValeriaJoin」を探して開いてみてください。
ここで焦点を当てるのはResult Scriptの使い方です。これはゲーム中しゃべられる会話テキストが表示されたあとに裏で実行されるスクリプトです。下のピクチャはValeriaをコンパニオンとして連れて行くことにした時、Valeriaが使用するTopicです。つまりこの会話を皮切りにValeriaが仲間になる部分です。
 

GG_T_007.jpg

 
「そうね・・・あなたは一見してイヤな感じでもないし〜」という会話をValeriaとした後、裏でResult Scriptに記述したスクリプトが実行されます。上のピクチャでは全て表示しきれていませんが、このTopicのResult Scriptには以下のスクリプトが書かれています。

GGValCamp.disable
set GGValeriaQuest.bIsCompanion to 1
set GGValeriaQuest.bDoClass to 1

「GGValCamp.disable」はつまりValeria's Campを無効にしろという関数です。これにより地図上からValeria's Campの表示は消え去ります。
 
次に「set GGValeriaQuest.bIsCompanion to 1」ですが、これは「bIsCompanion」という変数に1をセットしています。
 

変数の使い方について Edit

変数はその中に主に数字をとっかえひっかえ入れ替えて使用するわけですが、これは前述したConditionについての説明でもあったようにスイッチとして使用することが多いです。
 
変数を宣言した時にはその変数の中には数字の「0」が入っています。そして何かをきっかけとしてそれに「1」をセットして、言い換えればスイッチをオンの状態にさせることで、別のアクションを起こさせるようにするわけです。
今「bIsCompanion」に1をセットしました。
これはValeriaがコンパニオンになったという状態を表すもので、コンパニオン状態というスイッチがオンになったと言い換えてもいいかもしれません。
これにより、例えば下のピクチャのValeriaのステータスを見るというTopicが表示されるようになります。
 

#ref(): File not found: "GG_T_008.jpg" at page "開発資料/コンパニオン改造手引/GG_CJE解体新書"

 
Conditionsのリストの真ん中の項目に注目すると、「bIsCompanion」に「1」がセットされているならばこのTopicは表示されるということになっているのがわかると思います。
変数はこのような会話の表示のオン・オフという小さな事柄から、例えばその人物と夜に幽霊が現れるという話をしたことにより、「bIsGhost」という名の変数に1をセットして、夜に幽霊を出現させるようにするといった大掛かりな事柄をするスイッチともなりえるのです。ちなみにCSWikiでは「スイッチ」という言い方ではなくて「フラグ」という使い方をよくしています。
 
なお、他の人が作成したMODにおいて、それら変数を見るとき、その名前でだいたいどのようなことにそれを使用しているのか見当をつけることはできますが、実際に何をしているのかはよくわかりません。当然にその使用されている変数がどこで使用されているのか自分で探す必要があるわけです。そしてそれら変数がどこのスクリプトに書かれているのかを探す際にCSのメインツールバーのEdit/Find Textを利用すると大変便利です。
 
最後に「set GGValeriaQuest.bDoClass to 1」ですが、これは「bDoClass」という名の、Valeriaのクラス設定のフラグをオンにしたことを表します。この「bDoClass」変数は「GGValeriaScript」で使用されています。
具体的には557行以下の

if GGValeriaQuest.bDoClass == 1
  MessageBox "彼女の戦闘スタイルを決定してください: ", "近接戦闘", "遠距離戦闘", "近/遠距離折衷戦闘", "魔法戦闘", "ステルス戦闘"
  set GGValeriaQuest.bDoClass to 0
endif

に処理が引き継がれます。
MessageBox関数はゲーム上にメッセージを表示させるものであり、またボタンを表示させて、プレイヤーに選択肢を与えることも可能となるものです。"近接戦闘", "遠距離戦闘", "近/遠距離折衷戦闘", "魔法戦闘", "ステルス戦闘"はゲーム中ボタンとして表示され、選択されたボタンに応じてValeriaのクラスがランダムで決定されます。
 
これ以降の行でどのようにしてクラスが決定されるているかは詳しく説明しませんので、CSWikiで関数を調べながら自分で読み解いてみてください。
 

GGのスクリプトの使い方について Edit

GGのスクリプトの構造は万事がこのような形で作られています。Valeriaに「〜をしろ」という会話をした後、Result Scriptで「何かの変数名」に1がセットされ、その変数が書かれているスクリプト本体の方で

if GGValeriaQuest「何かの変数」 == 1
 →行動をする(例えばステータスを表示させたり、戦闘の方法を切り替えさせる)

といった形をとるわけです。
Result Scriptでそれらスクリプト処理をそのまま書き込んでしまう事もできますが、Result Scriptでは通常のスクリプトウィンドウで作成するスクリプト(これをResult Scriptの対義語としてNamed Scriptと呼びます)よりも制限がかかっています(具体的には変数の制限とBegin-Endブロックが使用できません)。また長いスクリプトだと、Result Script自体のウィンドウ枠が小さいのであとで非常に見づらくなると思います。
 
そんなわけで、1行で終わるような短いスクリプトでないのなら、変数を一度クッションとして利用して、スクリプトウィンドウの方でそれ以降のアクションを書いていくのが賢明でしょう。
 

終わりに Edit

最初はGGの機能に着目して、随時そのスクリプトの記述は何を表しているのか説明していこうと考えていましたが、それはスクリプトの基礎がわかっているならばCSWikiの関数辞書を見れば読み解いていけるものだと思い直しました。それならばCSでMODを作成しようとする人にとって何がその障害になりえるのかと考えてみた所、CSWikiで言葉足らずになっている部分が結構あるのではないかと思い至りました。本チュートリアルはそんな、初心者でもない、しかしCSをまだうまく使いこなせない人を対象にして書いてみたつもりです。
拙いチュートリアルになりましたが、これがあなたのMOD製作の手助けに少しでもなれば幸いです。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-12-27 (木) 13:02:26