redruin1 / factorio-draftsman

A complete, well-tested, and up-to-date module to manipulate Factorio blueprint strings. Compatible with mods.
MIT License
91 stars 17 forks source link

Framework for version differences as the expansion draws near #108

Open redruin1 opened 8 months ago

redruin1 commented 8 months ago

With the advent of the Factorio DLC expansion coming out later next year, there is highly likely to be a difference in blueprint string format for Factorio version 2.0, as well as for versions of the game with and without the expansion. Just based on the current few FFFs that they've released, a number of obvious changes from Factorio 1.x are already present:

This exposes a more overall problem with Draftsman, in which Draftsman is only really designed to create/validate the latest version of Factorio's blueprint string... but this becomes difficult to maintain when there are now 2 latest versions. This issues a number of questions: how should Draftsman handle a blueprint string from with the expansion contents when loading in a configuration that doesn't have the expansion, and vice-versa? How even is Factorio itself going to remedy these distinctions between game versions? Is the factorio-data git repo going to handle having two similar but distinct versions of the game?

Ideally Draftsman should implement a versioning system that could create and validate valid blueprint strings for the detected Factorio version and configuration. Presumably, this also means that the user might want to be able to manually specify a version of Factorio to create blueprint strings for, which currently would require modifying the factorio-data submodule included with the module in order to probably work. Currently, this is only circumstantially possible (and not easily or straightforward to boot), and only true for versions of Factorio greater than 1.0; previous versions are not supported.

Doing this would not only allow for the expansion to be accepted seamlessly when it releases, but also opens up the possibility to read old blueprint strings from older versions of Factorio. This would probably be less prioritized than the expansion, but these could be worked on as desired as PRs from interested parties, provided a straightforward solution is already in place.

redruin1 commented 5 months ago

In addition:

tephyr commented 5 months ago

I have only used Draftsman to create vanilla game blueprints, but I would like the ability to create ones specific to the expansion pack, in addition to targeting the new base game.

So as a consumer of Draftsman, I think the most Draftsman-like & Pythonic way of handling game data would be:

Having the usage of Draftsman require something like a set_engine_version() call on instantiation to tell Draftsman what game & mod data to load, and throwing an error if the user doesn't have the required data, feels like a clean way to handle the different versions. And while it would be nice to switch in code to a different base game version (vs. getting a different branch of Draftsman), I think that would be better done only if people express a want and are willing to dig in & submit PRs.

So yes, I think versioning Draftsman's behavior is the way to go.

redruin1 commented 5 months ago

Currently, Draftsman isn't versioned alongside Factorio; previous versions of Draftsman point to previous versions of Factorio, but going back to previous versions of Draftsman to work with game data from previous versions would sacrifice any modern improvements to the module which is undesirable. It would be nice to have the most modern, stable version of Draftsman be backwards compatible with previous versions of the game without having to downgrade Draftsman itself.

For static game data, I think the best option moving forward is to add a argument to draftsman-update which allows you to specify the version of Factorio you want, e.g:

draftsman-update --factorio-version 1.1.50

... which would pull the commit with that tag from Wube's github and update the submodule inside Draftsman, and then update the configuration so that the data is reflected when you use the module. This requires write access to the Draftsman installation, but Draftsman already requires this when running draftsman-update.

The other half would be making Draftsman handle it's configuration much more flexibly than currently. For example, Linked belts and containers didn't exist prior to Factorio 1.0.20 or so; and since those items are expected to exist in Draftsman currently, setting Factorio to a version prior to that will cause Draftsman to error. (This particular issue has been fixed on 2.0, but I'm not quite done there yet.)

A lot also rests on exactly how Wube themselves are going to handle the expansion, both internally in the game as well as with their external repositories, so the best we can really do right now is speculate in regards to that. I think I'll probably shoot for previous version compatibility first as a "warm up", hopefully before the expansion finally drops.

tephyr commented 5 months ago

Adding the --factorio-version option sounds like a good path forward.

I was about to ask for a way to check the current version of game data (ala Python's sys.version_info), but I see that's already available in draftsman.data.mods.mod_list. So if Draftsman can be updated to handle some backward-compatibility in base game behavior, like the linked belts & containers, I think that would put it in a good position with all the changes coming out.

redruin1 commented 5 months ago

@tephyr In addition to querying draftsman.data.mods.mod_list (which essentially has the base game version as kind of a technicality due to the way Factorio treats it's base version as a mod), you can also use draftsman.__factorio_version_info__, similar to how other python modules will label their versions:

>>> import draftsman
>>> draftsman.__version__
'1.1.0'
>>> draftsman.__version_info__
(1, 1, 0)
>>> draftsman.__factorio_version__
'1.1.88.0'
>>> draftsman.__factorio_version_info__
(1, 1, 88, 0)

This value is updated with draftsman-update as well.

redruin1 commented 2 months ago

As of now, --factorio-version is now a command line argument on 2.0:

~ > draftsman-update --no-mods --factorio-version 1.1.100 --verbose
Current Factorio version: 1.1.107
Different Factorio version requested (1.1.107) -> (1.1.100)
Changed to Factorio version 1.1.100

Reading mods from: D:\SourceCode\repos\Python\factorio-draftsman\draftsman\factorio-mods

Discovering mods...

...

In addition to all specific version tags, the command also reserves the phrase "latest", which will default to the latest tag available. Tested it against every version >= 1.0.0, and the test suite still seems to pass.