プログラミング・動画編集 備忘録

プログラミングや動画編集についての備忘録です

Starfield:ファイル解析3(メモ)

概要

前回までで Starfield - Localization.ba2 が大体解析出来て、読み取りと編集は行えるようになった。
今回から、ゲームのメインデータとなる Starfield.esm の解析を進めて行こうと思う。

なお、今更ながらだがバイナリ解析については素人なので、用語など正しい言葉は使えてない。
また、ファイル構造などについてこれまでのシリーズで使われている用語も正しい言葉ではないのでご注意を。

基本的な構造

簡単といえば非常に簡単で、次のような感じ。

基本的に「レコード」という単位で考え、「レコード」の中には複数の「フィールド」がある。
そして複数の「レコード」は「グループ」でまとめられる。
ただし、最初の TES4 はユニークレコードのような扱いになると思われ「グループ」でまとめられない。

名称 説明
TES4 最初に TES4 から始まるのでこれまでのシリーを踏襲していると考えられるが、そのままSkyrimと同じではなさそう。
(参考)https://en.uesp.net/wiki/Skyrim_Mod:Mod_File_Format/TES4
総バイト数 4byte固定で、フィールド情報部分の総バイト数。
レコード情報 16byte固定で、4byte区切りで何かの情報としていると思われる。5~8byte部分はIDのはず。
フィールド情報 ここから「フィールド」の情報が「総バイト数」分続く。
「フィールド」は最初の4byteでフィールドのタイプを示し、その後 2byte でそのフィールドのデータ長を示し、データ本体と続く形。
GRUP グループの始りを示す。
総バイト数 4byte固定で、GRUP を含むグループ全体の総バイト数。
グループ情報 16byte固定で、最初の4byteでレコードタイプを示し、その後の12byteは不明。( 00 で埋められている)

このため、GRUP 部分から 8byte先の 4byte を読み込めばそのグループのレコードタイプがわかり、次の GRUP まで読み飛ばすといった感じでデータを読み込むと、Starfieldでのレコードタイプは次のものがある事がわかる。
こちらでの内容とも一致する。
Starfield Mod:Mod File Format - Starfield Wiki

Starfield.esmで定義されているレコードタイプ(175件)

GMST
KYWD
FFKW
LCRT
AACT
TRNS
TXST
GLOB
DMGT
CLAS
FACT
AFFE
HDPT
RACE
SOUN
SECH
ASPC
AOPF
MGEF
LTEX
PDCL
ENCH
SPEL
ACTI
CURV
CUR3
ARMO
BOOK
CONT
DOOR
LIGH
MISC
STAT
SCOL
PKIN
MSTT
GRAS
FLOR
FURN
WEAP
AMMO
NPC_
LVLN
LVLP
KEYM
ALCH
IDLM
BMMO
PROJ
HAZD
BNDS
TERM
LVLI
GBFT
GBFM
LVLB
WTHR
WTHS
CLMT
SPGD
REGN
NAVI
CELL
WRLD
NAVM
DIAL
INFO
QUST
IDLE
PACK
CSTY
LSCR
ANIO
WATR
EFSH
EXPL
DEBR
IMGS
IMAD
FLST
PERK
BPTD
ADDN
AVIF
CAMS
CPTH
VTYP
MATT
IPCT
IPDS
ARMA
LCTN
MESG
DOBJ
DFOB
LGTM
MUSC
FSTP
FSTS
SMBN
SMQN
SMEN
DLBR
MUST
EQUP
SCEN
OTFT
ARTO
MOVT
COLL
CLFM
REVB
RFGP
AMDL
AAMD
MAAM
LAYR
COBJ
OMOD
ZOOM
INNR
KSSM
AORU
STAG
IRES
BIOM
NOCM
LENS
OVIS
STND
STMP
GCVR
MRPH
TRAV
RSGD
OSWP
ATMO
LVSC
SPCH
AAPD
VOLI
SFBK
SFPC
SFPT
SFTR
PCMT
BMOD
STBH
PNDT
CNDF
PCBN
PCCN
STDT
WWED
RSPJ
AOPS
AMBS
WBAR
PTST
LMSW
FORC
TMLM
EFSQ
SDLT
MTPT
CLDF
FOGV
WKMF
LGDI
PSDC
SUNP
PMFT
TODD
AVMD
CHAL

とりあえず作ったツールで読み取るとこんな感じ。

なお、次のレコードタイプについては単純な構造ではないので、レコードタイプを読み取った後は次の GRUP までスキップしている。

CELL
WRLD
QUST
SFTR
PNDT

また、その他特殊なもので現時点で把握しているものとして XXXX というフィールドタイプはデータ長が 4byte となっており、データ本体部分の中でさらにフィールドが入れ子になっているような構造となっている。
あとは、FULL フィールドはローカライズの文字列のIDを示しているようなので、とりあえず紐付けて表示させてみているがほぼ間違いなさそう。

惑星関連のデータについて

レコードタイプ STDT は惑星関連のデータの中でも、星系に関するレコードと思われる。
理由としては出てくる名称やローカライズのテキストのリンク先が星系の名称のため。
また、フィールドには XXXX フィールドも含まれており、XXXX フィールド内には Houdini という統合型3DCGソフトウェアのプリセットのテキスト情報と思われる情報などが含まれている。
Houdini の事は全然知らないが3DCGということで、星系内での惑星の配置などの3DCGに関する情報なのかもしれない。

Houdini 関連のデータと思われるもの(ボーア星系)

#PSI_PRESET
version 2.0a
opvalues
{
version 0.8
folder1 [ 0 locks=0 ]   (   0   )
exportcomplete  [ 0 locks=0 ]   (   0   )
exportquick [ 0 locks=0 ]   (   0   )
documentationbutton [ 0 locks=0 ]   (   0   )
reloadscripts   [ 0 locks=0 ]   (   0   )
dump_complete_save  [ 0 locks=0 ]   (   0   )
complete_dump_load  [ 0 locks=0 ]   (   0   )
spawnnoise1 [ 0 locks=0 ]   (   0   )
autofill_lazy_setup [ 0 locks=0 ]   (   0   )
exportmatspec   [ 0 locks=0 ]   (   0   )
ck_using_houdini    [ 0 locks=0 ]   (   "on"    )
clean_up_files  [ 0 locks=0 ]   (   "on"    )
use_checkpoints [ 0 locks=0 ]   (   "off"   )
show_debug_controls [ 0 locks=0 ]   (   "off"   )
folder3_1   [ 0 locks=0 ]   (   0   0   0   0   0   0   0   0   0   0   0   )
planet_name [ 0 locks=0 ]   (   Bohr    )
resolution  [ 0 locks=0 ]   (   2048    )
terrain_name    [ 0 locks=0 ]   (   fractured_01    )
terrain_name_secondary  [ 0 locks=0 ]   (   volcanic_01 )
terrain_name_surface_A  [ 0 locks=0 ]   (   rock_08 )
terrain_name_surface_B  [ 0 locks=0 ]   (   cratered_05 )
biomecount  [ 0 locks=0 ]   (   1   )
folder_archetype_ocean  [ 0 locks=0 ]   (   0   )
preset_filter_gp_ocean  [ 0 locks=0 ]   (   ""  )
preset_gp_ocean [ 0 locks=0 ]   (   None    )
preset_name_entry_gp_ocean  [ 0 locks=0 ]   (   ""  )
save_ocean  [ 0 locks=0 ]   (   0   )
load_ocean  [ 0 locks=0 ]   (   0   )
edit_mode_gp_ocean  [ 0 locks=0 ]   (   "off"   )
folderoceanarchetype    [ 0 locks=0 ]   (   0   )
has_ocean   [ 0 locks=0 ]   (   "off"   )
ocean_multiparm_index   [ 0 locks=0 ]   (   0   )
ocean_order_index   [ 0 locks=0 ]   (   0   )
sea_level   [ 0 locks=0 ]   (   0.5 )
coast_depth [ 0 locks=0 ]   (   0.019999999552965164    )
coast_depth2    [ 0 locks=0 ]   (   0.0070000002160668373   )
sea_preerosion_blend    [ 0 locks=0 ]   (   0.5 )
ocean_landmass_add  [ 0 locks=0 ]   (   0.25    )
coast_color [ 0 locks=0 ]   (   0.75099998712539673 0.72366398572921753 0.54597699642181396 0.5 )
height_smooth   [ 0 locks=0 ]   (   0.05000000074505806 )
detail_layer_count  [ 0 locks=0 ]   (   0   )
archetype_biome_folder__4   [ 0 locks=0 ]   (   0   )
preset_filter_gp_surface    [ 0 locks=0 ]   (   ""  )
preset_gp_surface   [ 0 locks=0 ]   (   rock_default    )
preset_name_entry_gp_surface    [ 0 locks=0 ]   (   ""  )
save_gp_surface [ 0 locks=0 ]   (   0   )
load_gp_surface [ 0 locks=0 ]   (   0   )
edit_mode_gp_surface    [ 0 locks=0 ]   (   "off"   )
folder8 [ 0 locks=0 ]   (   0   )
folder0 [ 0 locks=0 ]   (   0   )
terrain_erosion_type    [ 0 locks=0 ]   (   thermal )
global_color_hue_shift  [ 0 locks=0 ]   (   0   )
global_color_saturation_shift   [ 0 locks=0 ]   (   0   )
global_color_value_shift    [ 0 locks=0 ]   (   0   )
terrain_mask_intensity  [ 0 locks=0 ]   (   1   )
terrain_normal_intensity    [ 0 locks=0 ]   (   0.5 )
folder18    [ 0 locks=0 ]   (   0   )
terrain_erosion_type_secondary  [ 0 locks=0 ]   (   mixed   )
terrain_mask_intensity_secondary    [ 0 locks=0 ]   (   0.69999999999999996 )
terrain_normal_intensity_secondary  [ 0 locks=0 ]   (   0.69999999999999996 )
terrain_secondary_use_mask  [ 0 locks=0 ]   (   "off"   )
terrain_secondary_mask  [ 0 locks=0 ]   (   lower   )
terrain_secondary_use_color [ 0 locks=0 ]   (   "off"   )
terrain_secondary_color [ 0 locks=0 ]   (   light   )
terrain_secondary_color_hue_shift   [ 0 locks=0 ]   (   -0.20000000000000001    )
terrain_secondary_color_saturation_shift    [ 0 locks=0 ]   (   0.10000000000000001 )
terrain_secondary_color_value_shift [ 0 locks=0 ]   (   -0.20000000000000001    )
terrain_secondary_mask_contrast [ 0 locks=0 ]   (   0   )
terrain_secondary_mask_position [ 0 locks=0 ]   (   0.5 )
folder9 [ 0 locks=0 ]   (   0   )
folder10    [ 0 locks=0 ]   (   0   )
surface_mask_A_is_terrain   [ 0 locks=0 ]   (   "on"    )
surface_mask_A_auto_pick_texture    [ 0 locks=0 ]   (   "on"    )
surface_mask_A_texture_pick [ 0 locks=0 ]   (   blank_white )
surface_mask_A_tiling   [ 0 locks=0 ]   (   8   )
surface_mask_single_biome_mask_A    [ 0 locks=0 ]   (   lower   )
surface_mask_single_biome_color_A   [ 0 locks=0 ]   (   dark    )
surface_mask_A_color_hue_shift  [ 0 locks=0 ]   (   0   )
surface_mask_A_color_saturation_shift   [ 0 locks=0 ]   (   0   )
surface_mask_A_color_value_shift    [ 0 locks=0 ]   (   0   )
surface_mask_A_albedo_blend_mode    [ 0 locks=0 ]   (   Lerp    )
surface_mask_A_albedo_alpha [ 0 locks=0 ]   (   0.94999999999999996 )
surface_mask_A_blend_intensity  [ 0 locks=0 ]   (   1   )
surface_mask_A_normal_intensity [ 0 locks=0 ]   (   0.14999999999999999 )
surface_mask_A_mask_contrast    [ 0 locks=0 ]   (   0   )
surface_mask_A_mask_position    [ 0 locks=0 ]   (   0.5 )
folder11    [ 0 locks=0 ]   (   0   )
surface_mask_B_is_terrain   [ 0 locks=0 ]   (   "on"    )
surface_mask_B_auto_pick_texture    [ 0 locks=0 ]   (   "on"    )
surface_mask_B_texture_pick [ 0 locks=0 ]   (   blank_white )
surface_mask_B_tiling   [ 0 locks=0 ]   (   7   )
surface_mask_single_biome_mask_B    [ 0 locks=0 ]   (   upper   )
surface_mask_single_biome_color_B   [ 0 locks=0 ]   (   light   )
surface_mask_B_color_hue_shift  [ 0 locks=0 ]   (   0   )
surface_mask_B_color_saturation_shift   [ 0 locks=0 ]   (   0   )
surface_mask_B_color_value_shift    [ 0 locks=0 ]   (   0   )
surface_mask_B_albedo_blend_mode    [ 0 locks=0 ]   (   Lerp    )
surface_mask_B_albedo_alpha [ 0 locks=0 ]   (   0.94999999999999996 )
surface_mask_B_blend_intensity  [ 0 locks=0 ]   (   1   )
surface_mask_B_normal_intensity [ 0 locks=0 ]   (   0.25    )
surface_mask_B_mask_contrast    [ 0 locks=0 ]   (   0   )
surface_mask_B_mask_position    [ 0 locks=0 ]   (   0.5 )
folder17    [ 0 locks=0 ]   (   0   )
surface_dirt_blend_1    [ 0 locks=0 ]   (   0.10000000000000001 )
surface_dirt_blend_2    [ 0 locks=0 ]   (   -0.10000000000000001    )
surface_dirt_blend_3    [ 0 locks=0 ]   (   0.20000000000000001 )
surface_dirt_blend_4    [ 0 locks=0 ]   (   0.10000000000000001 )
surface_dirt_blend_5    [ 0 locks=0 ]   (   0.20000000000000001 )
surface_dirt_blend_6    [ 0 locks=0 ]   (   0.10000000000000001 )
surface_dirt_blend_7    [ 0 locks=0 ]   (   -0.10000000000000001    )
surface_dirt_blend_8    [ 0 locks=0 ]   (   0.20000000000000001 )
dirt_noise  [ 0 locks=0 ]   (   0   )
surface_dirt_noise_1    [ 0 locks=0 ]   (   dirt_01 )
surface_dirt_noise_2    [ 0 locks=0 ]   (   dirt_02 )
surface_dirt_noise_3    [ 0 locks=0 ]   (   dirt_03 )
surface_dirt_noise_4    [ 0 locks=0 ]   (   dirt_04 )
surface_dirt_noise_5    [ 0 locks=0 ]   (   dirt_05 )
surface_dirt_noise_6    [ 0 locks=0 ]   (   dirt_06 )
surface_dirt_noise_7    [ 0 locks=0 ]   (   dirt_07 )
surface_dirt_noise_8    [ 0 locks=0 ]   (   dirt_08 )
folder15    [ 0 locks=0 ]   (   0   )
surface_mask_A_texture  [ 0 locks=0 ]   (   PlanetFeatureMesasSparse01  )
surface_mask_B_texture  [ 0 locks=0 ]   (   PlanetNoiseSharp01  )
archetype_biome_folder__3   [ 0 locks=0 ]   (   0   )
preset_filter_gp_colormap   [ 0 locks=0 ]   (   ""  )
preset_gp_colormap  [ 0 locks=0 ]   (   barren_gray_01  )
preset_name_entry_gp_colormap   [ 0 locks=0 ]   (   ""  )
save_gp_colormap    [ 0 locks=0 ]   (   0   )
load_gp_colormap    [ 0 locks=0 ]   (   0   )
edit_mode_gp_colormap   [ 0 locks=0 ]   (   "off"   )
use_color_map   [ 0 locks=0 ]   (   "on"    )
colorize_hue    [ 0 locks=0 ]   (   0.29279701581052231 )
colorize_saturation [ 0 locks=0 ]   (   0.57343604278692817 )
colorize_amount [ 0 locks=0 ]   (   0.22559040275665831 )
folder5 [ 0 locks=0 ]   (   0   )
folder12    [ 0 locks=0 ]   (   0   )
colorize_hue_range  [ 0 locks=0 ]   (   0   1   )
colorize_saturation_range   [ 0 locks=0 ]   (   0.40000000000000002 0.59999999999999998 )
colorize_amount_range   [ 0 locks=0 ]   (   0.20000000000000001 0.25    )
folder13    [ 0 locks=0 ]   (   0   )
colorize_base_value [ 0 locks=0 ]   (   0.5 )
colorize_layer_A_hue_shift  [ 0 locks=0 ]   (   -0.01   )
colorize_layer_A_saturation_shift   [ 0 locks=0 ]   (   -0.20000000000000001    )
colorize_layer_A_value_shift    [ 0 locks=0 ]   (   0.5 )
colorize_layer_B_hue_shift  [ 0 locks=0 ]   (   0.01    )
colorize_layer_B_saturation_shift   [ 0 locks=0 ]   (   0   )
colorize_layer_B_value_shift    [ 0 locks=0 ]   (   0.10000000000000001 )
folder14    [ 0 locks=0 ]   (   0   )
color_map_height_blend  [ 0 locks=0 ]   (   0.10000000000000001 )
color_map_terrace_blend [ 0 locks=0 ]   (   0.10000000000000001 )
color_map_edge_blend    [ 0 locks=0 ]   (   0.10000000000000001 )
color_map_edge_blend_invert [ 0 locks=0 ]   (   "off"   )
color_map_crazy_map [ 0 locks=0 ]   (   0.02    )
color_map_crazy_map_distort [ 0 locks=0 ]   (   0.10000000000000001 )
color_map_brightness    [ 0 locks=0 ]   (   1   )
color_map_saturation    [ 0 locks=0 ]   (   1   )
color_map_contrast  [ 0 locks=0 ]   (   1   )
color_map_sharpen   [ 0 locks=0 ]   (   3   )
color_map_sharpen_width [ 0 locks=0 ]   (   0.0050000000000000001   )
color_map_sharpen_blend [ 0 locks=0 ]   (   0.5 )
color_map_blur_width    [ 0 locks=0 ]   (   0.050000000000000003    )
color_map_blur_blend    [ 0 locks=0 ]   (   0.25    )
color_map_velocity_blur_amount  [ 0 locks=0 ]   (   10  )
color_map_velocity_blur_blend   [ 0 locks=0 ]   (   0.25    )
folder16    [ 0 locks=0 ]   (   0   )
color_map_dirt_blend_1  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_2  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_3  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_4  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_5  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_6  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_7  [ 0 locks=0 ]   (   0.01    )
color_map_dirt_blend_8  [ 0 locks=0 ]   (   0.01    )
folder_terrain_influence_biome__3   [ 0 locks=0 ]   (   0   )
color_map_terrain_influence_blend_amount    [ 0 locks=0 ]   (   0.75    )
color_map_terrain_influence_mountains   [ 0 locks=0 ]   (   0.20000000000000001 )
color_map_terrain_influence_canyons [ 0 locks=0 ]   (   -0.20000000000000001    )
color_map_terrain_influence_sediment    [ 0 locks=0 ]   (   0.050000000000000003    )
color_map_terrain_influence_debris  [ 0 locks=0 ]   (   0.050000000000000003    )
color_map_terrain_influence_flow    [ 0 locks=0 ]   (   0.10000000000000001 )
color_map_terrain_influence_water   [ 0 locks=0 ]   (   -0.050000000000000003   )
color_map_terrain_influence_mesa    [ 0 locks=0 ]   (   0.02    )
color_map_terrain_influence_cliffs  [ 0 locks=0 ]   (   -0.02   )
colormaptagsfolder  [ 0 locks=0 ]   (   0   )
tag_report  [ 0 locks=0 ]   (   0   )
taglist_gp_planet_type  [ 0 locks=0 ]   (   10  )
folder7 [ 0 locks=0 ]   (   0   )
is_custom   [ 0 locks=0 ]   (   "off"   )
force_cooker    [ 0 locks=0 ]   (   "on"    )
print_verify_success    [ 0 locks=0 ]   (   "off"   )
interactive_verify  [ 0 locks=0 ]   (   "off"   )
process_decal_mat   [ 0 locks=0 ]   (   "off"   )
bypass_verify_error [ 0 locks=0 ]   (   "off"   )
do_debug_prints [ 0 locks=0 ]   (   "off"   )
disable_autofills   [ 0 locks=0 ]   (   "on"    )
is_test_sphere  [ 0 locks=0 ]   (   "off"   )
is_biome_test   [ 0 locks=0 ]   (   "off"   )
buttonforcetextures [ 0 locks=0 ]   (   0   )
buttoncleanupfiles  [ 0 locks=0 ]   (   0   )
scanforerrors   [ 0 locks=0 ]   (   0   )
printcookattributes [ 0 locks=0 ]   (   0   )
test_button [ 0 locks=0 ]   (   0   )
Setup_Compositing   [ 0 locks=0 ]   (   0   )
forcefinalwrangle   [ 0 locks=0 ]   (   0   )
exportdata2 [ 0 locks=0 ]   (   0   )
exportdata  [ 0 locks=0 ]   (   0   )
cleanfiles  [ 0 locks=0 ]   (   0   )
export  [ 0 locks=0 ]   (   0   )
exportocean [ 0 locks=0 ]   (   0   )
exportcolormap  [ 0 locks=0 ]   (   0   )
exportdecalalpha    [ 0 locks=0 ]   (   0   )
exportsurfacemasks  [ 0 locks=0 ]   (   0   )
exportrings [ 0 locks=0 ]   (   0   )
checkp4 [ 0 locks=0 ]   (   0   )
sync_p4_asset_folders   [ 0 locks=0 ]   (   0   )
print_all_parameters    [ 0 locks=0 ]   (   0   )
print_all_attributes    [ 0 locks=0 ]   (   0   )
folder2 [ 0 locks=0 ]   (   0   )
use_p4  [ 0 locks=0 ]   (   "on"    )
render_farm_mode    [ 0 locks=0 ]   (   "off"   )
path_data   [ 0 locks=0 ]   (   $DEADLINE_OUTPUT/Data   )
path_source [ 0 locks=0 ]   (   $DEADLINE_OUTPUT/Source )
path_temp   [ 0 locks=0 ]   (   //escvault/Remote_Render/DEADLINE_JOB_OUTPUTS/60a3edf0e8ca8dcaf4e146fb/task_23  )
path_data_input [ 0 locks=0 ]   (   $DEADLINE_INPUT/Data    )
path_source_input   [ 0 locks=0 ]   (   $DEADLINE_INPUT/Source  )
folder6 [ 0 locks=0 ]   (   0   )
resolution_surface_mask [ 0 locks=0 ]   (   512 )
terrain_name_filter [ 0 locks=0 ]   (   ""  )
diffusealphaglobal  [ 0 locks=0 ]   (   1   )
biome_data_resolution   [ 0 locks=0 ]   (   256 )
tile

とりあえず今回はここまで。