int19h / WarBender

WarBender: a Mount & Blade: Warband save game editor
MIT License
26 stars 7 forks source link

"Expected exactly 1 fields, but got 0" #8

Open Fidel-Chan opened 4 years ago

Fidel-Chan commented 4 years ago

Hello

I recently downloaded this editor and i tried to use it on a modded module but right after i select the savegame and the module.ini the following error pops up:

https://imgur.com/a/fx5fiKH

I was hoping to get a little help, thanks in advance

int19h commented 4 years ago

Can you share item_kinds1.txt for that module?

Fidel-Chan commented 4 years ago

item_kinds1.txt

Fidel-Chan commented 4 years ago

Sorry for the late response mate

abysskeeper commented 3 years ago

I don't know it'll helped but i had the same problem with Perisno 1.20 and it worked when i restarted my pc.

int19h commented 3 years ago

So this is kind of a broken-by-design issue...

When I wrote the parser for those files, I mostly reverse-engineered it from the files themselves using Native module as a reference (and to some extent also by looking at https://github.com/Kushulain/MnBSaveGameEditor). They seemed like they have meaningful line breaks, with multiple lines per record, but of well-defined structure in terms of those breaks that clearly identifies the records. This is nice, because it means that the parser doesn't have to understand each record entirely - only the fields that the app needs. So that's how I coded it.

After carefully reading the process_*.py files in the Warband module system that generate those .txt files, turned out it's not actually the case. So far as I can tell, the .txt files are actually meant to be read scanf-style, with all whitespace treated largely the same; line breaks in the output are just making it more readable. The records themselves are, effectively, variable-length, and values of some fields specify how many other fields follow, or, sometimes, whether a field appears or not. Thus, to properly parse the file, the parser needs to read each record in its entirety, field by field.

Now, it just so happened that in Native, the ad-hoc scheme that I devised around using line breaks to parse records worked - largely by accident. On the other hand, in this module (and, presumably, any other that is affected), some slight difference made it so that a line break is inserted at one point where it never occurred in Native. And so, here we are.

Unfortunately I don't see any easy hack here that might make it work "good enough" with the current implementation. It just needs to be redone - LineReader needs to be replaced completely with a scanf-style field reader, and all the ...Definitions classes under /WarBender/Modules need to be rewritten on top of that. This is quite a lot of work, because the way those classes are implemented currently, they often skip over entire lines without even trying to parse them, when they expect to see no relevant data there - now they'll have to parse those, too. In some cases, they might be able to just skip a predetermined number of fields; but whenever there's any variable-length data there, it has to parse at least the length to skip the fields correctly after. Similarly, when there's a flag that affects whether another field is present or not, it must parse the flag before it can skip (or not) the field.

Basically, one has to strictly follow the logic in the corresponding process_*.py - for example, TroopDefinitions must follow process_troops.py.

This is one of those things that I will try to gradually fix when I have time to spare. But, given Bannerlord, maintaining https://github.com/int19h/csx is a priority for me, so it probably won't be done anytime soon. If someone wants to take a crack at it to fix it sooner, I will be happy to help them figure out the codebase and do a pull request.

Ecthelion75 commented 3 years ago

Hi, is this issue still being worked on? I have the same issue with the Between Empires mod.

int19h commented 3 years ago

Not at the moment, no. I'll happily accept pull requests to fix this, though.