gamedataのTDF — エンジンの設定テーブル
gamedata/にあるファイルは、エンジン自体を設定するTDFテキストファイルです。移動クラス、武器のダメージカテゴリ、陣営データ(UIのレイアウト、建設メニュー、初期ユニット)、サウンドの割り当て、そしていくつかの小さなルックアップテーブルを設定します。(ユニットを追加するのではなく)ゲームのルールを変えるMODは、ほとんどの場合ここに手を入れます。
このページでは、gamedataのファイルのうち特に役立つものを説明します。どれもINIに似たTDFの文法を使います。パーサーの細部についてはTDFを参照してください。
Tip
自分で試す
ls $(kbot ctx path)/gamedata/
# The web UI renders these as collapsible section trees
kbot mount $(kbot ctx path) --server
# → browse to gamedata/sidedata.tdf, then sidedata > [CANBUILD]
ファイルの概要
| ファイル | 制御する内容 |
|---|---|
sidedata.tdf |
陣営ごとのUIレイアウト、初期のコマンダー、建設メニュー。gamedata/で最大のファイルです。 |
moveinfo.tdf |
移動クラス。各「MovementClass」がどの地形を通れるか。 |
weapons.tdf |
武器TDFの文法のリファレンス文書(ほとんどがコメントで、実行時のテーブルではありません)。 |
category.tdf |
ユニットのカテゴリの、人が読める説明。見た目だけのものです。 |
sound.tdf |
ユニットごとのサウンドカテゴリ(FBIのSoundCategory=から参照されます)。 |
allsound.tdf |
UIとゲーム内イベントのサウンド(ボタンのクリック、スコアバーの通知音、BGM)。 |
los.tdf |
視界の調整(地形ごとの視界半径の補正)。 |
meteor.tdf |
隕石嵐のパラメーター(一部のキャンペーンマップで使われます)。 |
unitview.tdf |
ゲーム内のユニット情報パネルのレイアウト。 |
buildinfo.tdf |
建設メニューのホットキーとツールチップの文字列。 |
version.tdf |
ロビーが報告するゲームのバージョン文字列。 |
translate.tdf |
UI文字列のローカライズ用ルックアップテーブル。 |
help.tdf |
ゲーム内ヘルプの項目。 |
MOD制作で重要な3つは、sidedata.tdf(建設メニュー、陣営)、moveinfo.tdf(移動クラス)、weapons.tdf(データではなく文書です。実際の武器はweapons/*.tdfにあります)です。
moveinfo.tdf — 移動クラス
ユニットのFBIはMovementClass=KBOTSS2(または同様のもの)を宣言します。エンジンはそのクラスをmoveinfo.tdfで検索し、ユニットが通れる地形を決めます。
TA 3.1cは[CLASS0]から[CLASS31]までのセクション(それぞれの名前で最初に現れるセクション)だけを読み、クラスをName=で、大文字と小文字を区別せずに、番号の小さいスロットから順に探します。ユニットのクラスが見つかると、クラスの値がユニット自身のFootprintX/FootprintZ、MaxWaterDepth、MinWaterDepth、傾斜のキーを完全に置き換えます(コマンダーのMaxSlope=20はTANKDS2の32に取って代わられます)。クラスが省いたキーには、FBIの値ではなく、下に示すゲームの既定値が使われます。クラスを持たないユニットや、ゲームが見つけられないクラスを指定したユニットは、自身のFBIのキーを同じ既定値で読みます。KBot Studioのユニットのメタ情報、サンドボックス、ホストした対戦は、この方法で移動を解決します。
[CLASS0]
{
Name=KBOTSS2; // Class name referenced from FBIs
FootprintX=2; // Cells wide (16-px units)
FootprintZ=2; // Cells deep
MaxWaterDepth=12; // Deepest water it can enter
MaxSlope=32; // Steepest land slope it can climb
}
[CLASS3]
{
Name=TANKDH3;
FootprintX=3;
FootprintZ=3;
MaxWaterDepth=100; // Heavy tank — can ford deep water
MaxWaterSlope=30; // Slope limit *underwater* (separate from MaxSlope)
MaxSlope=15;
}
フィールド
| フィールド | 型 | 意味 |
|---|---|---|
Name |
string | ユニットのFBIのMovementClass=から参照されるクラス識別子。大文字と小文字を区別しません。 |
FootprintX, FootprintZ |
int | 経路探索用のフットプリント。16 pxの属性セル単位です。ユニットのFBIのフットプリントを置き換えます。クラスが省いた場合は0です。 |
MaxWaterDepth |
int | ユニットが入れる最も深い水深(地形の高さの単位)。0は陸上専用です。既定は10000(どの深さでも可)。ホバークラフトのクラスはこれを省いているので、ホバークラフトはFBIの記述にかかわらず、どんな水の上でも進みます。 |
MinWaterDepth |
int | 必要な最小の水深(艦船、潜水艦)。既定は-10000(最小なし)です。 |
MaxSlope |
int | ユニットが陸上で登れる最も急な傾斜(単位は2π / 256ラジアン)。既定は255で、MaxWaterSlopeが上限になります。 |
BadSlope |
int | ユニットが減速する傾斜(遅くはなるが、通れなくはならない)。既定はMaxSlopeの半分で、MaxSlopeが上限になります。 |
MaxWaterSlope |
int | MaxSlopeと同じもので、水中で適用されます。既定は255(制限なし。ホバークラフトに使われます)。 |
BadWaterSlope |
int | BadSlopeの水中版。既定はMaxWaterSlopeの半分です。 |
命名規則
クラス名は、その形状を短いタグで表しています。Cavedogの慣習は次のとおりです。
| 接頭辞 | 意味 |
|---|---|
KBOT |
二足歩行のKボット |
TANK |
装軌車両・装輪車両 |
BOAT |
水上の艦船 |
SPID |
スパイダー(多脚の歩行機械) |
HOVER |
ホバークラフト |
その後に接尾辞SS / SF / DS / DH / SH(小型、深い、重いなど)と、フットプリントの数字が続きます。この命名は慣習にすぎません。エンジンはName=を、中身を解釈しないキーとして扱います。
Important
同じMovementClass=を持つ2つのユニットは、経路探索の振る舞いを共有します。KBOTSS2をMaxWaterDepth=50に変えると、小型のKボットはすべて水の中を歩いて渡るようになります。ユニットごとに調整したい場合は、代わりに新しいクラスを追加してください。
sidedata.tdf — 陣営ごとの設定
これはgamedata/で最も長いファイルです。3つの異なる役割をまとめているためです。
- 陣営の宣言 — 名前、接頭辞、コマンダー、フォント、色。
- HUDのレイアウト — ゲーム内UIのすべてのステータスバー、ラベル、ボタンのピクセル座標。
- 建設メニュー — 各建設ユニットが建設できるものを列挙する
[CANBUILD]セクション。
陣営のブロック
[SIDE0]
{
name=ARM;
nameprefix=ARM;
commander=ARMCOM; // UnitName of the commander unit
intgaf=ARMINT; // GAF used for intro screen
font=console; // FNT for general text
fontgui=armbutt; // FNT for buttons
energycolor=208; // Palette index for energy bars
metalcolor=224; // Palette index for metal bars
// …followed by ~60 HUD coordinate sub-sections
[LOGO] { x1=132; y1=5; x2=152; y2=25; }
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
[METALBAR] { x1=218; y1=12; x2=345; y2=14; }
...
}
[SIDE1] { name=CORE; ... }
| フィールド | 意味 |
|---|---|
name |
陣営の表示名(カテゴリの照合にも使われます)。 |
nameprefix |
ローカライズの検索に付け加えられる接頭辞の文字列。 |
commander |
その陣営のコマンダーユニットのUnitName。 |
intgaf |
陣営の選択中に表示されるGAFシーケンス。 |
font / fontgui |
HUDの文字とボタンに使うFNTファイル。 |
energycolor / metalcolor |
HUDのバーのパレットインデックス(palette.palのインデックス)。 |
TA 3.1cは陣営を[SIDE0]、[SIDE1]、…の順に読み、最初に欠けた番号のところか、5つ読んだところで止まります。それ以外の名前のセクション([SIDE01]、[SIDE2]が欠けた後の[SIDE3]、6つ目の陣営)は決して読まれません。また、読み込まれる各陣営には下に挙げるHUDの長方形(kbot-ioのta.SideRectangles)がすべて必要で、1つでも欠けるとゲームは陣営を1つも読み込みません。スタジオのサンドボックスの陣営選択も、同じ陣営を提示します。
HUD座標のサブセクション
目に見えるHUDの要素はどれも、x1/y1/x2/y2のピクセル座標を持つ[NAME]ブロックです。座標は基準解像度640×480に対するもので、それより高い解像度ではエンジンが拡大縮小します。
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
エネルギーバーの位置を変えるには、4つの数値を編集します。見た目を描き直すには、HUDがその位置の描画に使うGAF(unitview.tdfで設定)を差し替えます。
[CANBUILD]の建設メニュー
静的な建設メニューの定義です。各建設ユニットについて、ゲーム開始時に建設できるものを列挙します。
[CANBUILD]
{
[ARMCOM]
{
canbuild1=ARMSOLAR; // Slot 1 on the build menu
canbuild2=ARMWIN;
canbuild3=ARMESTOR;
canbuild4=ARMMSTOR;
canbuild5=ARMMEX;
...
}
[ARMLAB]
{
canbuild1=ARMCK;
canbuild2=ARMPW;
...
}
}
スロット番号は、建設メニューのページ上の位置です。TAの建設メニューは2列×3行のグリッドなので、1ページには6個のスロットがあります。canbuild1〜canbuild6が1ページ目、canbuild7〜canbuild12が2ページ目、という具合です。
TA 3.1cがこのテーブルを読む方法は次のとおりです(kbot-ioのCanBuildBuilder.BuildList。kbot document、ユニットビューアー、サンドボックスの建設メニューはこれに従います)。
- リストを持つのは、
Builder=1をFBIで設定したユニットだけです。それ以外のユニットのサブセクションは無視されます。 - ゲームは最初の
[CANBUILD]セクションを読み、その中で、建設ユニットの名前が付いた最初のサブセクションを(大文字と小文字を区別せずに)読みます。 canbuild1、canbuild2、…と読み、最初に欠けた番号で止まります。canbuild1=ARMSOLAR; canbuild3=ARMLAB;なら項目は1つです。- どのユニットにも一致しない名前は飛ばされ、リストに入るユニットは最大で30個です。ダウンロードの項目(後述)によって、建設ユニットのメニューが31個になることもあります。(以前の文書には1ページに12スロットとするものもありましたが、実際のゲーム内のグリッドは6です。)基本ゲームの各建設ユニットのページ配置については、TAの建設ツリーのリファレンスを参照してください。
Important
MODでユニットを追加するためにsidedata.tdfを編集してはいけません。建設メニューにユニットを追加する、Cavedogお墨付きの方法は、MODのほかのファイルと一緒にdownload/<UNITNAME>.tdfファイルを配布することです。エンジンは起動時に、すべてのdownload/*.tdfをsidedata.tdfの静的な[CANBUILD]テーブルに統合します。
sidedata.tdfを編集してよいのは、HUDと建設メニューのレイアウト全体を書き換えるトータルコンバージョンを配布する場合だけです。Cavedog自身の拡張パックCore Contingencyでさえ、新しいユニットはsidedata.tdfを変更せずに、download/*.tdfで追加しています。
TDF: [MENUENTRY]とMOD制作のチュートリアルを参照してください。
weapons.tdf — 武器TDFのリファレンス
名前に反して、gamedata/weapons.tdfはほとんどがコメントです。これはCavedogが公開した武器TDFの文法のリファレンスで、ゲームが読み込むことはありません。実際の武器の定義はweapons/*.tdfにあり、武器1つにつき1セクションです(TDFを参照)。kbot documentは、gamedata/weapons.tdfのセクションを武器として一覧に載せません。
武器テーブル
TA 3.1cは、weapons/の直下にある(サブディレクトリは含まない).tdfファイルから、列挙した順に256個の武器スロットのテーブルを作ります。
- セクションは、その
ID=が示すスロット(0〜255)に入ります。IDのないセクションや、範囲外のセクションは飛ばされます。 - 後から現れた同じ
IDのセクションは、同じファイル内でも後のファイルでも、前のものを置き換えます。 - ユニットの
Weapon1/Weapon2/Weapon3、ExplodeAs、SelfDestructAsはセクションを名前で指します。名前は(大文字と小文字を区別せずに)、その名前のセクションを持つ最も番号の小さいスロットに解決されます。 - 値は先頭の数値部分として読まれます。
weaponacceleration=13O;は13になり、不正な値があってもファイルの残りが捨てられることはありません。 - 構造が壊れていると、ゲームはファイル全体を拒否するので、障害箇所より前のセクションも含めて、そのファイルの武器は1つも読み込まれません。壊れた構造とは、
]や{のないセクションヘッダー、ファイルの終わりまでに=のないテキストや;のない値、セクションの途中で終わるファイル、空のファイルです。ほかのファイルは影響を受けません。(どのセクションにも属さない余分な}は拒否されません。ゲームはそこで読むのをやめ、それまでの内容を保持します。) rangeがなければ32767、minbarrelangleがなければ-11.25度です。reloadtimeは整数のティック単位で数えます(1秒あたり30で、reloadtime*30を切り捨て。0.35なら10ティック、0.333秒後に再装填)。turnrateの単位は1秒あたりの角度単位です(65536で1周)。
KBot Studio、パック、kbot hostは、どれもこのテーブルを通して武器を解決します。ゲームが拒否するファイルや、飛ばしたり置き換えたりするセクションは警告として報告されます(kbot packはそれを表示し、スタジオは/api/studio/weapons/warningsで提供します)。
rendertype=4のスプライト
rendertype=4の武器はanims/fx.gafの2Dスプライトを飛ばし、どのスプライトかはcolor=で選びます。0はcannonshell、1はplasmasm、2はplasmamd、3はultrashell、4は再びplasmasmです。それ以外の値(EARTHQUAKEのcolor=255など)では、スプライトは描かれません。スプライトは、GAFのフレームの表示時間にかかわらず、発射の瞬間からゲームの1ティックにつき1フレームずつ進みます。
リファレンスのコメントには、次のことが書かれています。
- 3つの武器の基本型:
ballistic、lineofsight、dropped。武器TDFはどれも、このうち1つを1に設定しなければなりません。 - 射程、速度、加速度 — ピクセル単位、およびピクセル毎秒単位。
- 効果範囲 — ピクセル単位の半径。
edgeeffectivenessで端での減衰の割合を指定します(例:0.5なら端でダメージが半分)。 - バーストと拡散 —
burst、burstrate、sprayangle。 - 2段階の武器 — スターバースト型の発射体のための
twophase、weapontype2、flighttime。 - 描画タイプ —
rendertype=Nで、3Dモデル、パレット付きビットマップ、ビームなどを選びます。
[DAMAGE]サブセクションには、目標のカテゴリごとのダメージ補正が入ります。
[FLAMETHROWER] {
...
[DAMAGE]
{
default=10; // Damage applied to anything not listed
corpyro=2; // Pyros are nearly fire-proof
}
}
[DAMAGE]のキーはユニット名です。列挙されたユニットはdefault=の代わりにそのダメージを受け、それ以外のユニットはすべてdefault=のダメージを受けます。値は16ビットに収められます。死亡時の爆発(ExplodeAs、SelfDestructAs)も同じテーブルを使います。CORPYRO_BLASTは既定で60のダメージを与えますが、パイロには15です。
category.tdf — ユニットのカテゴリの説明
カテゴリのトークンを人が読める文字列に対応させる、見た目だけの平坦なリストです。エンジンはこれをユニット情報パネルに表示します。
[Plant] { description = Unit Creation plant; }
[KBOT] { description = Some type of units; }
[Tank] { description = Some type of units; }
[Metal] { description = Some type of units; }
説明の代わりのダッシュは、Cavedogが意図せず残した定型文です。ほとんどのMODはこのファイルに手を付けませんが、説明をきちんとしたフレーバーテキストに置き換えるものもあります。変更してもゲームプレイには影響しません。
sound.tdfとallsound.tdf
WAV / サウンドで扱っています。要点は次のとおりです。
sound.tdf— ユニットのカテゴリごとのサウンドの割り当て([ARM_COM]、[ARM_KBOT]セクション)。FBIのSoundCategory=から参照されます。ゲームは23のイベントを読み、それぞれKEY、続いてKEY1、KEY2、…と、最初に欠けた番号まで読みます。allsound.tdf— UI全体のサウンドの割り当て([BIGBUTTON]、[SKIRMISH]、[BGM])。
実例 — 移動クラスを追加する
「ごく浅い水を渡れる船」のクラスを作るには、次のようにします。
gamedata/moveinfo.tdfの末尾に追加します。[CLASS20] { Name=AMPHIB3; FootprintX=3; FootprintZ=3; MaxWaterDepth=100; // Deep water OK MaxSlope=20; // Reasonable land climbing MaxWaterSlope=200; // Smooth underwater movement }ユニットのFBIに次のように書きます。
MovementClass=AMPHIB3;クラスのフットプリントと制限がFBI自身のものを置き換えるので、ユニットの
FootprintX/FootprintZ/MaxWaterDepthキーはもう意味を持ちません。まとめます。
kbot hpi pack ./mymod --target mymod.ufo
これで、ユニットは陸と水の両方を切れ目なく移動できます。
Note
読まれるのは[CLASS0]から[CLASS31]だけです。[CLASS32]、[CLASS100]、[HOVERXL]にあるクラスは決して見つからず、それを指定したユニットは自身のFBIのキーにフォールバックします。32未満の空いているスロットを選んでください(製品版はCLASS0からCLASS14を使っています)。同じスロット名を持つ2つ目のセクションは無視されます。
典型的なサイズ
| ファイル | Cavedogのgamedata/で観測された範囲 |
|---|---|
sidedata.tdf |
約50 KB |
moveinfo.tdf |
約3 KB(15〜20クラス) |
sound.tdf |
約20 KB(300以上のカテゴリ) |
weapons.tdf |
約2 KB(ほとんどがコメント) |
category.tdf |
約1 KB |
| その他のgamedataファイル | それぞれ5 KB未満 |
注意点
Warning
gamedataのファイルの多くは、マップごとではなく、エンジンの起動時に1回だけ読み込まれます。変更を試すにはゲームを再起動する必要があり、ロビーを読み込み直すだけでは足りません。変更が「反映されなかった」と思い込むMOD制作者が、これによく引っかかります。
- 移動クラスのスロットは固定です。読まれるのは
[CLASS0]から[CLASS31]だけで、その範囲内なら番号が飛んでいてもかまいません。 - ほとんどのファイルでは、コメントは
/*…*/ではなく//ですが、weapons.tdfは両方を使っています。テスト用のパーサーは両方を受け付けますが、サードパーティのツールには受け付けないものもあります。 sidedata.tdfのHUD座標は640×480が基準で、それより高い解像度ではエンジンが拡大します。最近の解像度で座標を書かないでください。[CANBUILD]の番号に欠番があってはいけません。ゲームは建設ユニットのリストを最初に欠けたcanbuildNで読むのをやめるので、canbuild11の次がcanbuild14だと、14番目の項目とそれ以降のすべてが、エラーもなく失われます。- ゲームが見つけられない
MovementClassはエラーになりません。ユニットは何も言わずに自身のFBIのキーを使い、欠けているキーにはゲームの既定値を使います。たとえばMaxWaterDepthのないユニットは、深さ10000まで水の中を歩いて渡ります。