kwsch / pkNX

Pokémon (Nintendo Switch) ROM Editor & Randomizer
https://projectpokemon.org/home/forums/topic/48647-pknx-nintendo-switch-rom-editor-randomizer/
GNU General Public License v3.0
339 stars 106 forks source link

Label PersonalTable9 Field16 #295

Closed bWFpbA closed 1 year ago

bWFpbA commented 1 year ago

Field16 in PersonalTable9 is the base EXP addend, which is added to the base EXP calculated using the base stat total and the evo stage.

Y | Chansey: 237
Y | Blissey: 365
N | Poochyena: 12
N | Zigzagoon: 8
N | Zigzagoon-1: 8
N | Wurmple: 17
Y | Slaking: -50
Y | Happiny: 66
N | Audino: 234
N | Audino-1: 234
N | Archen: -9
N | Archeops: -21
N | Floette-5: 50
N | Wooloo: 68

I also looked into Field18, though I cannot figure out its usage. It appears to be set for Pokemon that have moves that can change types. For example, it was set for Sylveon in 1.0.0 only, either as a mistake or due to its hidden ability, Pixilate. It is also set for every Arceus and Silvally form, and they both have signature moves that change typing based on held item (Judgment, Multi-Attack).

Also, quick question - what is with Field2 being set as a FlatBufferStruct? From what I understand of the flatbuffer binary format, if a field is a struct, it will always have a non-zero field offset value within the vtable, which is not the case for Field2.

duckdoom4 commented 1 year ago

if a field is a struct, it will always have a non-zero field offset value within the vtable

To answer your question, that's not true by default. When running the flatcc.exe binary builder there's an option you can enable to force this behaviour.

For the other fields, did you compare with PLA's version? Fields will likely overlap with that one.

bWFpbA commented 1 year ago

if a field is a struct, it will always have a non-zero field offset value within the vtable

To answer your question, that's not true by default. When running the flatcc.exe binary builder there's an option you can enable to force this behaviour.

Could you elaborate on this? Is it an argument to flatcc, or is it set within the schema? If its an argument to flatcc, would it not affect the other structs as well? There are at least 4 others that have all-zero data for entry 0, but have a non-zero field offset within the vtable.

For the other fields, did you compare with PLA's version? Fields will likely overlap with that one.

I don't believe anything like Field18 is stored within the SS, BDSP or LA personal data structures. It looks to be new to SV, most likely related to the Tera mechanic.

kwsch commented 1 year ago

I assume it's that way so the game can check HasValue rather than checking if the struct fields are zero. Built in way to indicate if something is not in the dex by truth checking the field offset.

duckdoom4 commented 1 year ago

Could you elaborate on this?

Yes, this is from the flatc.exe -h help section: image

I'll asume that flatcc's builder also has this option available. As you can see, these args needs to be supplied to enable it, thus is disabled by default.

(In this case setting a value to null means setting the vtable offset to 0)

As for the other entries, I'd guess you can manually set field's with an object/array type to contain an empty array instead of null. Just like you can in c# (MyType[] array = null; or MyType[] array = Array.Empty<MyType>();)

bWFpbA commented 1 year ago

Could you elaborate on this?

Yes, this is from the flatc.exe -h help section: image

I'll asume that flatcc's builder also has this option available. As you can see, these args needs to be supplied to enable it, thus is disabled by default.

(In this case setting a value to null means setting the vtable offset to 0)

As for the other entries, I'd guess you can manually set field's with an array type to contain an empty array instead of null. Just like you can in c# (MyType[] array = null; or MyType[] array = Array.Empty<MyType>();)

I think you are confusing structs with strings.

duckdoom4 commented 1 year ago

So just to confirm we are talking about the same things: In flatbuffers 'vectors' are arrays of types, could be an object array (called a table) or an array of primitives (like int[]). Strings is just a vector of characters (char[]).

Then you have structs, also called objects or classes. In a flatbuffer these have seperate VTables.

Reading through your comment again, I realized you mean the second one and are not talking about a table or a vector.

In that case this applies:

You can manually set field's with an object/array type to contain an empty object/array instead of null.

aka. Field2 = null would result in a flatbuffer with Field2 = default or VTable's offset @ field2 = 0

That fact that a structure type generates a second VTable is seperate from the value of the field

duckdoom4 commented 1 year ago

So interesting plot twist... Turns out there's such a thing as 'inlined structs', and we didn't support that in FlatCrawler.

I wasn't aware this concept exists. Thanks to you pointing that out I'm now gonna add support for this.

bWFpbA commented 1 year ago

So interesting plot twist... Turns out there's such a thing as 'inlined structs', and we didn't support that in FlatCrawler.

I wasn't aware this concept exists. Thanks to you pointing that out I'm now gonna add support for this.

Haha, I don't think I pointed anything out - I was just getting confused on how the flatbuffer binary format works. For some reason, I thought that due to structs not being able to have defaults, that meant that the data would always have to be included within the binary. Though after doing some testing, I can see that this isn't the case.

duckdoom4 commented 1 year ago

Well, you are partially right.

Structs Similar to a table, only now none of the fields are optional (so no defaults either), and fields may not be added or be deprecated. Structs may only contain scalars or other structs. Use this for simple objects where you are very sure no changes will ever be made (as quite clear in the example Vec3). Structs use less memory than tables and are even faster to access (they are always stored in-line in their parent object, and use no virtual table).

_Source: https://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html_

So structs themselves are always fixed size. Meaning any values in the struct always have a value.

However, a struct can be placed inside of a table. The table can still remove values, so it can remove the entire struct.