sfall-team / sfall

sfall - Engine modifications for Fallout 2
https://sfall-team.github.io/sfall/
GNU General Public License v3.0
338 stars 40 forks source link

Dynamically register new protos #289

Open burner1024 opened 4 years ago

burner1024 commented 4 years ago

Would it be possible to add a function similar to add_extra_msg_file, but for protos? So that new protos could be shipped without .lst files, thus achieving better compatibility. Also could be useful to get their descriptions from a new msg. Maybe something like

int register_proto(name, type, msg_id - default by type)

new_msg = add_extra_msg_file("my.msg");
proto_id = register_proto("proname", type_misc, new_msg);

(or new_msg could be a string virtually appended to pro_misc.msg)

FakelsHub commented 4 years ago

Слишком много работы, т.к. нужно также подключать и графику таким же образом, иначе какой смысл от такого pro? В общем в долгий ящик это пока отложим.

Ps: в движке уже черт ногу сломит все утыкано хаками. Нужно потихоньку консервировать sfall и переходить к реализации falltergeist+sfall-features.

burner1024 commented 4 years ago

Ps: в движке уже черт ногу сломит все утыкано хаками. Нужно потихоньку консервировать sfall и переходить к реализации falltergeist+sfall-features.

Я только за, но от меня поддержка разве что моральная в этом вопросе :).

Lexx2k commented 4 years ago

A part of me really doubts that Faltergeist will ever be completed.

phobos2077 commented 1 year ago

I thought a lot about it recently. But I can't find a good solution yet, that doesn't involve big changes to engine core and file formats. If you add a new proto, you need to be able to save items with it. How would you do it if proto ID is dynamically assigned? How do you store this item in a savegame? (dat or map files)

An obvious solution for this is to change/extend format of game's proto, map and savegame dat files to support identifying art and prototypes by something like "mod_id + local_id", where mod_id is kind of a namespace, where this item came from, and local_id identifies it within that namespace/mod. But as you can see, it's a lot of work.

I'd suggest keeping this idea for CE where this bald approach can be more easily implemented, but then a lot of thought needs to be put into backwards compatibility and usability for modders...

However, turning on hacker mode.. PID's are 32 bits, we use 3 bits for object type, and up to about 16 bits (or less) for object index in LST file. What if we encode "mod id" into some of these unused bits, and then use last 16 bits as local ID instead of LST id? Will have to hook/override all functions that load proto by id (maybe it's just one function?).

Next step is some kind of local lst files for mods. So every mod will have it's ID either chosen by mod author (so we'll have to make sure there's no collisions..) OR, the game save file can remember which mods (by mod name or string ID) were assigned to which "mod PID". Let's say we use 8 bits for mod ID. This allows for 255 different mods to be installed per save game that add new stuff. And plenty of space for local ID's.

This is based on my understanding of how Gamebryo ESP files work. What do you think?

phobos2077 commented 1 year ago

Another issue - what if you want to reference this in a script, worldmap txt, or maps?

  1. For scripts, again we can track from which dat file/folder the mod was loaded and dynamically resolve all PIDs coming to script opcodes based on that. This can be solved by checking if a script proc was being invoked when get_proto is called. Should be easy.

  2. Map files. The same approach as scripts, but should be less code to change, just one that loads the map (creates objects based on PID's). Just track which mod this map came from and pull prototypes/art from appropriate mod-specific list.

  3. Worldmap.txt. This will require extending worldmap.txt format itself to allow additional format for specifying pids. A pair of string+number (mod unique ID + local id). This should be easy to do, but the issue is worldmap.txt itself is not friendly to several mods changing stuff. So a separate solution can be invented to tackles this.