Skyrim Mod ファイルフォーマット解説 - 1
はじめに
SkyrimのModファイルフォーマットについて解説?していきたいと思います。
Modのファイルフォーマットを知れば、プログラムを組んでデータを自動生成したり、Mod上の欲しい情報を取り出したりなどが行え、Mod製作にかかる時間を短縮できます。
また、プログラムを組まないにしても、バイナリエディタなどで直接情報を確認することも出来ます。
なお、Mod製作をはじめて4ヶ月ほどで、主にプログラムでModを生成することを進めていたので、逆に基本的なことを知らない部分もありますので、ご了承ください。
また、PS4で動作することを基本条件としていますので、PC版でなら簡単に出来ることを難しくやっている場合もあるかと思います。
ファイルフォーマットの情報は次のサイトで詳しく解説されていますので、自分なりに解析してきたことなどを書いてきたいと思います。
Tes5Mod:Mod File Format - The Unofficial Elder Scrolls Pages (UESP)
(※以降この際とのことはUESPと略します)
項目名の名称などは主にSSEEditでの名称を使っていきます。
使うツールなど
- Skyrim Special Edition Creation Kit Version 1.3.9.0
- SSEEdit 3.2
- Microsoft Visual Studio Community 2017 ( C# )
- BinaryEditor Stirling Version 1.31
- Binary Editor BZ Version 1.9.8.5
最小限の状態
Skyrim Special Edition Creation Kit(以降 CK)を起動し、Skyrim.esmにのみチェックを入れて読込み、ファイル保存したespファイルをバイナリエディタで表示すると次のようになっています。
ファイルの先頭4文字が"TES4"となっています。(その後の"I"はたまたま文字コードで"I"に一致しているだけです)
全てのModファイルはこの情報からはじまります。(※SkyrimはTES=The Elder Scrolls シリーズの5作目なのでTES5なのですが、ファイルフォーマットはTES4(Oblivion)の頃から変わらないということでしょうか。この辺はよくわかりません)
このModファイルは一切のデータがないため、"TES4"からファイルの終わりまで、Modファイルの基本情報のみが記載されています。この"TES4"からファイルの終わりまでの情報をファイッルヘッダーと呼ぶことにします。
では、これをSSEEditで読込んでみます。
SSEEditのウィンドウの右側に情報が表示されています。
まずは、Record Headerと書かれていて、その下にぶら下がっている項目を見てきます。
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | TES4 | |
DataSize | 73 | |
Record Flags | ||
FormID | 0 | |
Version Control Info 1 | 0 | |
Form Version | 44 | |
Version Control Info 2 | 0 |
このレコードヘッダーはModのファイルフォーマットを理解する上で重要な要素です。
一部例外がありますが、Modのファイルフォーマットの構造は次のようになっています。
Modファイル + ファイルヘッダー (レコード形式) + グループ - グループヘッダー + レコード - レコードヘッダー + フィールド - フィールドヘッダー - フィールドデータ
今解説している部分がファイルヘッダーで、これはレコード形式となっています。
レコードとは武器であれば1つ分の武器情報を扱う情報の固まりです。
グループとはレコードを包括した情報の固まりです。
レコードはレコードヘッダーから始まり、その後に続く情報がフィールドとなります。
フィールドは武器であれば、ダメージの値など、レコードで扱われる各種の情報の固まりです。
SSEEditで続きの情報を見て行きます。
Record Header の後に、 HEDR - Header とあります。これがフィールドです。
SSEEdit上では一部わかりませんが、フィールドはまず、次のフィールドヘッダーがあります。
名称 | データ型(サイズ) | 説明 |
---|---|---|
Signature | char[4] | フィールドがどのようなデータであるかを示す4文字の名称。フィールド名が同じでもレコードが異なれば扱う情報は異なる可能性があるので注意 |
Data Size | ushor | フィールドデータのサイズフィールドヘッダーのサイズは含まないので注意 |
※ushorのサイズは2byte、(別名uint16など)
実際のデータを見てみます。
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | HEDR | |
DataSize | 12 |
"TES4"レコードの"HEDR"フィールドの型情報など
名称 | データ型(サイズ) | 説明 |
---|---|---|
Version | float | UESPでの説明では「ほとんどのファイルで0.94; Update.esmの最近のバージョンでは1.7です。」とのこと |
Number of Records | uint | 全レコード数。(解析しきれていませんが、単純にカウントしても数が合いません・・・) |
Next Object ID | uint | 次のオブジェクトID(FormID)、CK上で何かを追加した際に使われるかと思われます。 |
実際のデータです。
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Version | float | |
Number of Records | uint | |
Next Object ID | uint |
※UESPでは、Number of Records(UESPでの表記はnumRecords)はint32、Next Object ID(UESPでの表記はnextObjectId)はulongとなっていますが、ここではC#を中心として扱うので、C#での表現とします。また、C#でのlong, ulongは8byte、C++は4byteのようなので、混乱なきよう。なお、レコードカウントについてはマイナスにはならないはずなので、一応uintとしています)
では、SSEEditで以降の項目を見て行きますが、次の"OFST"と"DELE"は灰色になっています。
これは、"TES4"レコードで扱われるフィールドで、かつファイル上での順番的にはこの順番になっているであろうフィールドですが、ファイル上ではデータが無いため、表示されていません。必須項目ではないということですね。どの項目が必須かなどはUESPのサイトで確認するのがいいかと思われます。
次のデータです。
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | CNAM | |
DataSize | 8 | |
CNAM - Autohr | DEFAULT |
※フィールドで扱う文字列は終端がNULLになるものと、そうでないものがあるため注意が必要です。基本的にはDataSizeを参照すれば大丈夫ですが、プログラムで扱う際には、終端がNULLかそうでないかのチェックが必要になります。
Master Files - MAST
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | MAST | |
DataSize | 11 | |
MAST - Filename | DEFAULT |
Master Files - DATA
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | DATA | |
DataSize | 8 | |
DATA - Unknown | 0 |
※マスターファイルはそのModでの前提ファイルです。フィールドはHEDRのように、フィールドデータ内で複数の情報を扱っているケースと、このMaster Filesのように、複数のフィールドが連続してある固まりとしていることもあります。例えば、マスターファイルが複数ある場合には次のようになっています。
※このような形式は多数あるため、プログラムでデータを取り込んで書きかえたい場合、並び順に注意する必要があります。例えば、コンテナなどは、コンテナ何に格納されているアイテムを示すのに、コンテナ内のアイテム数を示すフィールドがあり、それに続いて、コンテナのアイテムを示すフィールドがアイテム数分続きます。
INTV - Unknwon
表示名 | 内容 | バリナリ上での表示 |
---|---|---|
Signature | INTV | |
DataSize | 4 | |
DATA - Unknown | 1 |
と、このように管理されています。
通常はこの後に"GRUP"の4文字があり、その後4byteにグループのデータサイズがあり、データサイズ分読み飛ばすと、また次の"GRUP"の4文字があります。
それについては次回解説していきたいと思います。以上。