Well, I made quite a few wrong assumptions in that first post. The info that you posted has been really helpful, but I haven't figured out a basic struct for the base ability block yet. In fact, after looking at how skills and feats are stored in the file, at times it feels more like a big hash table than a collection of indexed blocks. Or maybe it is a bit of both, since I see evidence of some ordering and domain-based clustering.
If only for convenience, using the block structure I outlined in the first post, there are some interesting patterns. I'm going to use the
Strength as an example:
- The
Base Ability block seems to start with an index of sorts. I don't think it is always sequential for adjacent blocks, but for base abilities and skills it is.
Int32 index // 0x5E7 (BigEndian?)
Byte unknown // 0x0
- Then follows what appears to be a naming scheme of some kind, including a list of names that would make sense if they were linked to some values later.
Int8 + char[Int8] abilityType? // 0x4 + SBA2
Int32 nameCount // 0x6
Byte[] names // nameCount * (Name) { S4:C, S4:V, S4:MV, S4:VC, S4:MVC, BA2:N }
Byte[] unknown // byte[nCount]
Int8 + char[Int8] entityClass? // 0x3 + BA3
- Each name in the list is just the string length + the string itself.
Int8 + char[Int8] name // 0x4 + S4:C
- Then comes a completely unknown chunk, where I would expect some sort of values or flags that correspond to the previous list of names.
Byte[] unknown // byte[nameCount]
Int8 + char[int8] // 0x3 + ESI
Int32 esi1Val // 0x2
Int8 + char[int8] // 0x3 + ESI
Int32 esi1Val // 0x2
Byte[] unknown // 0x2
Byte unknown // 0x9
Int32 unknown // 0x2E
- Then come the actual ability values, as a pair of 32-bit integers.
- The first is the base ability value.
- The second could be the modified ability value, but it does not have any effect in either stats or skills when I changed it.
- This pattern is the same in the skill blocks.
Int32 baseAbilityValue // 0x5
Int32 modifiedAbilityValue // 0x5
- Then comes a strange byte array. This could actually be two flags and two 32-bit integers, but I have no idea what they could be used for. I'll explain in a moment, in the context of all blocks.
Byte[] seqIndex // 09 B7 03 00 00 0A 06 B8 03 00 00
- Finally comes the human-readable base ability or stat name.
Int8 + char[Int8] name // 0x8 + Strength
Now, about that strange byte array, what I called the seqIndex, when I looked what those bytes looked like in the different stat blocks, it appears they follow a sequential pattern:
STR: 09 B7 03 00 00
STR: 0A 06 B8 03 00 00
DEX: 09 BA 03 00 00
DEX: 0A 06 BB 03 00 00
AGI: 09 BD 03 00 00
AGI: 0A 06 BE 03 00 00
CON: 09 C0 03 00 00
CON: 0A 06 C1 03 00 00
PER: 09 C3 03 00 00
PER: 0A 06 C4 03 00 00
WIL: 09 C6 03 00 00
WIL: 0A 06 C7 03 00 00
INT: 09 C9 03 00 00
INT: 0A 06 CA 03 00 00
A part of this pattern even continues in the skill blocks. I wonder what this is.
Truly, I have no idea about which way to look at the file spec. But I think there are some obvious patters and it definitely can be edited, even if only for simple changes.
I would probably like to focus first on being able to read it from start to end. Then add a bit of editing functionality via CLI or a very basic UI. The problem I see is that I haven't found any block-sizes that I could use to speed-up the process of reading. It almost looks like it is all parsed in one pass.
I gotta say, though. It was never my intention to serialize the whole file. I'm just a curious fella who had a couple days free on the weekend. I just want to share what I can with the community, then try to play the actual game. But there is also the possibility that I enjoy mucking around game files more than playing the game. Oh well.
It'd be nice to have a community project where we can all contribute our little piece, I believe.
Yeah, I still have to write something about editing skills.