Grimrukh / soulstruct

Python tools for inspecting and modifying FromSoft games (mainly Dark Souls 1).
145 stars 16 forks source link

replace DS1 `EventArg` `HEADER_STRUCT`'s 4x padding with "unknown" field #18

Closed LukeLavan closed 2 years ago

LukeLavan commented 2 years ago

With the new Elden Ring commits, the base EventArg class began passing the UnkID field into its HEADER_STRUCT's pack function to generate the EventArg's binary representation. Here's the commit where this change happened..

For Dark Souls 3 and Elden Ring, the base EventArg's HEADER_STRUCT is overridden with a BinaryStruct that includes the UnkID as an int field called unknown. However, the Dark Souls 1 EventArg HEADER_STRUCT does not have the unknown field - instead, those four bytes are treated as a 4x padding field.

I suspect that this is because, as SoulsFormat confirms, these bytes were always zeroed out in every game before Sekiro. This shouldn't be an issue, except for BinaryStruct's pack function expecting there to be no extraneous keys in its input dict. The input dict is compiled from the keyword args passed into pack - which now includes the unknown field as of the recent Elden Ring commits. Thus, excluding the unknown field from DS1's EventArg HEADER_STRUCT causes the export process to error and fail. The error produced confirms this: ValueError:BinaryStruct.pack()input dictionary has extraneous keys: dict_keys(['unknown']).

This PR replaces the padding with the unknown field, avoiding the error and allowing the export process to succeed.

I should also note that the Bloodborne EventArg class does not have the unknown field defined for its HEADER_STRUCT either, so trying to export Bloodborne events should break in the same way. It seems like the bytes_to_write should be an unsigned int and the last four bytes should be the unknown field, matching DS3 and Elden Ring. I did not make this change because I can not test if this is correct (I don't have a PS4 ;P).

Grimrukh commented 2 years ago

Thanks for the detailed write-up and fix Luke!