Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Options: set old options api before the world is created #2378

Merged
merged 9 commits into from
Dec 16, 2023

Conversation

alwaysintreble
Copy link
Collaborator

What is this fixing or adding?

Old options API had options being set before worlds were created and some worlds relied on that. That behavior has been purposefully deprecated, but old API should still use it for back compat.

Also deprecates the old options API. these can be dropped and wait a version if really desired but we've already made the effort of making everyone aware and I'd prefer to properly deprecate it next version.

How was this tested?

unit tests. Also very low risk.

If this makes graphical changes, please attach screenshots.

@Jarno458
Copy link
Collaborator

I wont have time to test this until Sunday/Monday but this is meant to resolve #2374

one concern I do have is the plans for depreciation in 1 version, out of experience it takes multiple versions to get a world PR merged

@Jarno458 Jarno458 added is: bug/fix Issues that are reporting bugs or pull requests that are fixing bugs. affects: core Issues/PRs that touch core and may need additional validation. affects: release/blocker Issues/PRs that must be addressed before next official release. labels Oct 27, 2023
@black-sliver
Copy link
Member

I'm fine with the deprecation notice, since it is officially already deprecated.

As for the __init__, we have two options: 1. create the constructor in a way where it's useful (i.e. pass in player and multiworld and options) and a call to super().__init__ is what initializes the world for the multi, or 2. document that __init__ shouldn't be used for anything multiworld-related, but instead generate_early should be used.

While 1. sounds like cleaner OOP, I feel like 2. is more useful to our use-case, because that allows better scheduling, multiplexing, inspecting, multi-threading, etc. of the stages.

@alwaysintreble
Copy link
Collaborator Author

alwaysintreble commented Oct 27, 2023

While 1. sounds like cleaner OOP, I feel like 2. is more useful to our use-case, because that allows better scheduling, multiplexing, inspecting, multi-threading, etc. of the stages.

It was a deliberate design decision to not do 1 because passing the options to the world isn't very clean (for how AP works) and I explicitly don't want people doing multi-world things in the constructor. With the way item links functions, I think doubling down on this behavior is the correct path forward, since a world doing a whole bunch of stuff to "set up" in its constructor is really awful since none of that information will be used for an item link world. Will add documentation for this in a separate PR.

worlds/AutoWorld.py Outdated Show resolved Hide resolved
Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

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

lgtm unless @Berserker66 has a problem with the deprecation spam

@Berserker66
Copy link
Member

it's probably fine, my main worry is that this means explicitly having to be careful about using things that are created in generate early for item links filler, which I don't think we have a unittest for, and itemlinks aren't often tested ahead of borked.

@alwaysintreble
Copy link
Collaborator Author

#2081

@el-u
Copy link
Collaborator

el-u commented Oct 29, 2023

Given that the world instance is still in the process of being set up when its __init__ runs, I think it would be cleaner and more future-proof to outright forbid worlds from doing anything during instance creation.
We could easily make a test to ensure that for each individual world, __new__ and __init__ do not differ from those of World.

@black-sliver
Copy link
Member

There is some stuff that you may want to have in __init__, like setting up member variables. Using ClassVar defaults is generally worse in python than setting the defaults in __init__, because it's more likely to create a split dict and it's fragile for containers. Obviously you could use generate_early as a stand-in for that, but then there might be tests that don't use generate_early, but instead test helper functions on the world object, where the members should be initialized.

Breaking access to options and random once the old API is gone should be good enough to make sure __init__ is not abused.

@Jarno458
Copy link
Collaborator

Finely got to testing it, works fine, options are available in constructor. the deprication warnings do be a bit spammy tho

Running Item Plando
Running Pre Main Fill.
Filling the world with 337 items.
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.EnterSandman instead.
warnings.warn(self.log_message)
Balancing multiworld progression for 2 Players.
Beginning output...
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.UnchainedKeys instead. warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.EnterSandman instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.StartWithJewelryBox instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DownloadableItems instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.EyeSpy instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.StartWithMeyef instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.QuickSeed instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.SpecificKeycards instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.Inverted instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.GyreArchives instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.Cantoran instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.LoreChecks instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.BossRando instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.BossScaling instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DamageRando instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DamageRandoOverrides instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.HpCap instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.LevelCap instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ExtraEarringsXP instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.BossHealing instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ShopFill instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ShopWarpShards instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ShopMultiplier instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.LootPool instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DropRateCategory instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.FixedDropRate instead. warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.LootTierDistro instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ShowBestiary instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.ShowDrops instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DadPercent instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.RisingTides instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.Traps instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.DeathLink instead.
warnings.warn(self.log_message)
Generating output files (2/2).
Calculating playthrough.
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.UnchainedKeys instead. warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.EnterSandman instead.
warnings.warn(self.log_message)
T:\Git\Archipelago\Utils.py:767: UserWarning: Getting options from multiworld is now deprecated. Please use self.options.RisingTides instead.
warnings.warn(self.log_message)
Creating final archive at T:\Git\Archipelago\output\AP_34082977882593571005.zip
Done. Enjoy. Total Time: 47.24086639995221

@alwaysintreble
Copy link
Collaborator Author

Finely got to testing it, works fine, options are available in constructor. the deprication warnings do be a bit spammy tho

LGTM

@black-sliver
Copy link
Member

I'm not sure I want to hit merge. On one hand, the spam is good to get the attention of world devs, on the other hand, APWorlds can't really update until the next version is out. Should we maybe split this PR into two and merge the jarno fix now, and the rest later?

@alwaysintreble
Copy link
Collaborator Author

alwaysintreble commented Nov 1, 2023

I can if that's what we really want, but that'll push deprecation back 2 versions. Users also won't get the spam, and world devs can mute it by running with -O

@Jarno458
Copy link
Collaborator

Jarno458 commented Nov 2, 2023

Maybe make it log only 1 UserWarning per yaml or world type even?

@alwaysintreble
Copy link
Collaborator Author

Maybe make it log only 1 UserWarning per yaml or world type even?

each option under the old API is a separate dictionary, so the most I could do is once per option per world, which won't reduce the spam by much, if any.

@Jarno458
Copy link
Collaborator

Jarno458 commented Dec 4, 2023

So i added the release/blocker label to it as it broke for Timespinner on current main as Timespinner used to rely on reading the options in the constructor and i had no idea for what other worlds it might have been broken

However Timespinner moved its options usage to generate_early so this is nolonger a show stopped for Timespinner and since no other games have reported broken i think the plan is to move on so the blocker label can be removed i guess

@Berserker66 Berserker66 merged commit 7dff09d into ArchipelagoMW:main Dec 16, 2023
12 checks passed
Jouramie pushed a commit to Jouramie/Archipelago that referenced this pull request Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects: core Issues/PRs that touch core and may need additional validation. affects: release/blocker Issues/PRs that must be addressed before next official release. is: bug/fix Issues that are reporting bugs or pull requests that are fixing bugs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants