跳到主要内容

第 2 章:文件结构

VFP 1.3 是小端序的单文件二进制容器,不是 ZIP,也没有全局压缩层。读取器必须以文件末尾的 Footer 和其指向的活动 DIR0 为准;Payload 的物理排列不表达语义。

0 Header (64 B, VFPK)
64 已登记 Payload(连续写入;当前规范不要求对齐)
directoryOffset 活动 DIR0
fileSize - 64 Footer (64 B, VFPF)

2.1 Header(64 B)​

布局为 <4sHHIQQ32s4s>。

偏移类型字段规则
0char[4]magicASCII VFPK
4u16major1
6u16minor3
8u32headerSize64
12u64featureFlags提示性位图;目录才是实际依据
20u64directoryOffsetgeneration 0 的目录提示
28u8[32]sourceHash权威源哈希
60u8[4]reserved全零

Header 的 directoryOffset 不是活动目录的最终权威位置。追加保存后,Reader 必须使用最后一个 Footer。

2.2 Footer(64 B)​

布局为 <4sHHQQQI28s>。

偏移类型字段规则
0char[4]magicASCII VFPF
4 / 6u16major / minor1 / 3
8u64directoryOffset活动 DIR0 绝对偏移
16u64directoryLength完整目录长度
24u64generation初始值为 0
32u32directoryCrc32完整 DIR0 的 CRC-32
36u8[28]reserved全零

读取器必须拒绝目录超出 Footer 前边界、目录 CRC 错误或版本不是 1.3 的文件。VFP 1.3 不要求读取早期容器版本。

2.3 DIR0 与目录项​

DIR0 头为 12 B:<4sHHI>,字段依次为 DIR0、major=1、minor=3、entryCount。其后恰好有 entryCount 个 48 B 项,目录总长度为 12 + entryCount × 48。

目录项固定布局为 <4sIiIQQQII>:

tag: char[4]
codec: uint32
chunkId: int32
flags: uint32
offset: uint64
length: uint64
rawLength: uint64
crc32: uint32
reserved: uint32

codec 是唯一载荷编码依据:0=RAW8,1=RLE8。flags=0、reserved=0 为强制规则;未知 codec、非零 flags 或 reserved 必须拒绝,不能从 flags 猜测 RLE。crc32 覆盖存储态 Payload;RAW8 通常要求 length==rawLength。全局区段的 chunkId=-1。

VOX0 是唯一允许 codec=1 的现行标准区段;其它标准区段必须 RAW8。所有 Payload 必须位于 Header 后、活动 DIR0 前,且不得交叠。

2.4 featureFlags​

Header featureFlags 仅提示实际目录中的可选区段:bit 0 PRVW、1 MSH0、2 VOX0 可为 RLE8、3 VBUF、4 PMSH、5 RND0、6 ANM0、7 THMB、8 MATL、9 SKEL/VSKN[/ANIM]、10 XEXT。Reader 必须以 DIR0 为准。

2.5 最小与严格 Writer​

最小可恢复资产至少有 META、PAL0、CHIX、所有 Chunk 的 VOX0、DIR0 与 Footer。VoxelKit 严格校验/编译档还会为每个 Chunk 写入 MSH0,并建议写入 SCNE。VBUF、PMSH、RND0、ANM0、PRVW、THMB、MATL、Rig 与 XEXT 均是可选能力。