Skip to content

Conversation

@Xymanek
Copy link
Member

@Xymanek Xymanek commented Jun 24, 2021

@Xymanek Xymanek added the cooking Related to mod asset and Highlander cooking label Jun 24, 2021
@Xymanek Xymanek requested a review from robojumper June 24, 2021 08:20
@Xymanek Xymanek self-assigned this Jun 24, 2021
@Xymanek
Copy link
Member Author

Xymanek commented Jun 25, 2021

Overview of how this works:

This is using the "dlc cooking" functionality built into the cooker by passing the -DLCName= argument. This causes the cooker to use a copy of the shipped GPCD (instead of starting from scratch), which allows properly reusing base game TFCs. It also fixes gfxCommon, startup and native packages issues since the cooker loads them but doesn't cook - this allows us to get rid of "first cook" logic as well as build the mod in debug with no issues.

Deciding what to cook

Standalone SF

The cooker treats all XCOM 2 War of the Chosen SDK\XComGame\Content\(Mods|DLC)\[DLCName]\**.upk packages as Standalone SF and then uses the file timestamp to decide if cooking is needed or can be skipped for a specific one. There is one exception to this rule - the very first one alphabetically is always skipped (I didn't manage to find any reasoning either via logs or procmon). To counteract this, I put the actual packages into Content\Mods\[DLCName]\Standalone and create a guard package at Content\Mods\[DLCName]\aaaaaa\TEMP_DlcCookIteratorGuard_[DLCName].upk, which is guaranteed to be iterated first. This package is duplicated from EmptyPackage in X2MBC and contains a single instance of ObjectReferencer with the array being empty.

Maps

By default, the cooker will attempt to cook all maps it's aware of, dlc cooking or not, which is about 2.5k maps with around 15GB of output. Since this is obviously undesirable, I pass -skipmaps but this makes it skip the mod maps as well. To force it to cook a map, its name needs to be passed on the command line. However, unlike with the previous approach of cooking the "game", in dlc cooking mode, passing a map on the command line trumps all other checks, causing it to be recooked even if nothing has changed. To prevent this waste, I implemented a rudimentary timestamp-based check

Scripts

While possible, the benefit is minimal and there are associated gotchas so there is no automated way of doing so right now

Mod project layout

The ContentForCook folder has been split into 3 subfolders:

  • Standalone. Junctioned to Content\Mods\[DLCName]\Standalone
  • Maps. Included via changes to DefaultEngine.ini
  • Secondary. Included via changes to DefaultEngine.ini

The iteration/inclusion of packages in the Standalone folder is done by the cooker itself, while a similar approach is replicated by X2MBC for the Maps\**.umaps. Packages living outside of these folders will not be visible to the cooker.

This layout is designed to be intuitive (given the requirement for standalone packages) and naturally guiding the mod developers towards preventing unnecessary duplication of assets in their cooked packages.

ContentOptions.json remains, but sfStandalone and sfMaps options are removed (replaced by file iteration).

Drawbacks

There is no dlc-specific GPCD (every cooker invocation starts from the shipped one) so it doesn't know what textures are already included in your TFCs - editing a package with textures, even if the textures were not changed, will cause the textures to be dumped again into your TFCs. Fortunately the existing X2MBC cleaning functionality takes care of that (e.g. before building a version that will be published)

The map up-to-dateness check currently doesn't properly consider dependencies. I have some ideas how to approach this, but I don't see it as a huge blocker

Copy link
Member

@robojumper robojumper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach looks good! The loss of the GPCD is very unfortunate and something that IMO justifies recommending an additional VS Code task "WorkshopRelease"(?) that cleans before for a full rebuild (see VS Code Compound Tasks), and maybe the addition of a ModBuddy task.

Also this function is getting quite large, would it make sense to split it up some?

@Xymanek
Copy link
Member Author

Xymanek commented Jun 27, 2021

maybe the addition of a ModBuddy task

I implemented the "rebuild" task/option

this function is getting quite large, would it make sense to split it up some?

Agreed, with a caveat - IMO it needs to be split into its own class (e.g. like #43 does), since otherwise the variables will need to be prefixed with assetsCook and a lot of them have quite lengthy names already. In any case, I don't see this is as an immediate priority

Copy link
Member

@robojumper robojumper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, assuming this works for CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cooking Related to mod asset and Highlander cooking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants