redruin1/factorio-draftsman

Framework for version differences as the expansion draws near

redruin1 opened this issue ยท 6 comments

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:

  • New entities, items, recipes of all types
  • Quality items: how will blueprints request a legendary assembler? Will there be quality ranges for entities in blueprint strings?
  • Big electric pole range increased from 30 to 32
  • Blueprint ghosts can now be put on ghost tiles, presumably also including ghost concrete and similar
  • A rework of wire connections (perhaps in blueprint string format as well) and an increase in the number of power pole connections (at least 8, perhaps more or perhaps even configurable dependent on entity)
  • Red and Green circuit wires becoming abstract items instead of traditional recipes
  • Equipment ghosts (for spidertrons, and perhaps more)
  • New keys and parameters for rocket silos, likely with blueprint string counterparts

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.

In addition:

  • Circuit controlled assemblers (dear lord)
    • Enable disable + condition
    • Set recipe
    • Read ingredients
    • Read recipe finished + control signal(?)
    • Read working + control signal(?)
  • Flipping assembling machines of all types (dear lord)
  • Parameterized blueprints (bruh)
  • Train interrupts being part of schedules now
  • Train option "use destination train stop color"
  • RGB lamp color options
  • Removal of filter inserter and having filters be intrinsic to all Inserters
  • Swapping of nomenclature between Stack inserters and Bulk inserters

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:

  • default to the latest base game version
  • allow the user to specifically switch to any mod or expansion pack
  • only validate blueprints based on the user-given version(s): in other words, when importing a v1 blueprint into a v2 process, only validate with v2 rules (presumably on usage or export of the blueprint).

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.

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.

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.

@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.

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.