Skip to content

Apply best available single category modules by default#622

Open
craig-johnston wants to merge 5 commits intoYafc-CE:masterfrom
craig-johnston:auto_select_modules
Open

Apply best available single category modules by default#622
craig-johnston wants to merge 5 commits intoYafc-CE:masterfrom
craig-johnston:auto_select_modules

Conversation

@craig-johnston
Copy link
Copy Markdown

If no modules are set and the building takes special modules, apply default modules based on the milestones that are unlocked.
This is a QOL change for Py players in particular.

Adding recipe to create 1/s moss in existing YAFC:
image

Same action with this PR:
image

And example using Wood processing TURD at py3 - Saw blade 2 auto-selected:
image

This is a single function addition to calculate and apply the best module, so fairly isolated.
I've tested using Py mods.

  • Manually created module templates take precedence
  • Milestone unlocks are respected - If no modules are unlocked at the current milestone it just doesn't set any
  • Verified working with Bhoddos, Wood processing unit TURD and random sampling of other PyAL recipes
  • Normal buildings/recipes are not affected - It doesn't just start adding speed/prod modules for the normal recipes

As per comment in the code, I did not do a secondary sort. If two modules are unlocked at the same milestone, it'll just pick one for simplicity. If/when this case comes up there will be more info about which secondary sort option to take rather than guessing now and making the code more complex.

…efault modules based on the milestones that are unlocked.
@craig-johnston craig-johnston requested a review from DaleStan as a code owner May 4, 2026 02:47
Copy link
Copy Markdown
Collaborator

@veger veger left a comment

Choose a reason for hiding this comment

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

Code looks good to me.

I do wonder if we need to check some other mod packs to see if they are not broken by this, as we do not know how their modules work? (At least I do not... 😉)

Comment thread Yafc.Model/Model/ProductionTableContent.cs Outdated
@craig-johnston
Copy link
Copy Markdown
Author

I've tested briefly space age; it does nothing, as expected.
I'm not aware of many mods that play with modules. I'll try out sea block (angels/bobs) where there are agricultural modules added.
If there's a suggested list I can give them a try too

@veger
Copy link
Copy Markdown
Collaborator

veger commented May 4, 2026

I was indeed thinking about angels/bobs, as they introduce some new modules (at least back when I played them). I do not have a lot of experience with mod suites, so I do not have a list of which made changes to modules unfortunately.

If there are no others, we cannot test, and a (quick) angels/bobs is all that can be done...

@craig-johnston
Copy link
Copy Markdown
Author

Quick Angels/bobs test shows no conflict, it doesn't pick anything for the modules, same as space age.


//Update if this module is better (milestone order)
Bits moduleMilestoneOrder = Milestones.Instance.GetMilestoneResult(module.id);
if (bestModule == null || moduleMilestoneOrder.CompareTo(bestUnlockOrder) > 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if (bestModule == null || moduleMilestoneOrder.CompareTo(bestUnlockOrder) > 0) {
if (bestModule == null || moduleMilestoneOrder > bestUnlockOrder) {

It might just be me, but I always have to spend a lot of effort interpreting calls to CompareTo

Comment on lines +852 to +853
Bits moduleUnlockOrder = DataUtils.GetMilestoneOrder(module.id);
if (moduleUnlockOrder.CompareTo(recipeUnlockOrder) > 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Bits moduleUnlockOrder = DataUtils.GetMilestoneOrder(module.id);
if (moduleUnlockOrder.CompareTo(recipeUnlockOrder) > 0) {
if (module.IsAccessibleWithCurrentMilestones()) {

Based on the comment, I think this is the test you want. This way the relative unlock order isn't relevant, just whether the module is unlocked.

//Loop over all modules finding the one that is usable, unlocked, and unlocks latest according to milestones
foreach (Module module in Database.allModules) {
//Check module is in the building's allowed category
if (!string.Equals(module.moduleSpecification.category, moduleCategory, StringComparison.Ordinal)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if (!string.Equals(module.moduleSpecification.category, moduleCategory, StringComparison.Ordinal)) {
if (module.moduleSpecification.category != moduleCategory) {

As far as I can tell, operator != is the same as doing an explicit ordinal comparison.

//Update if this module is better (milestone order)
Bits moduleMilestoneOrder = Milestones.Instance.GetMilestoneResult(module.id);
if (bestModule == null || moduleMilestoneOrder.CompareTo(bestUnlockOrder) > 0) {
bestModule = module.With(Quality.Normal);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is Quality.Normal correct here, or should it be Quality.MaxAccessible?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants