-
Notifications
You must be signed in to change notification settings - Fork 840
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
OSRS: Fixes to Logic errors related to Max Skill Level determining when Regions are accessible #4188
Conversation
…it unconditionally
…the skill training rules now
…idge to south varrock without farms. This has been fixed
Co-authored-by: Exempt-Medic <[email protected]>
worlds/osrs/__init__.py
Outdated
entrance.access_rule = lambda state, item_name=item_name: state.has(item_name, self.player) | ||
continue | ||
|
||
entrance.access_rule = lambda state, item_name=item_name.replace("*",""): state.has(item_name.replace("*",""), self.player) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering why this wasn't changed to set_rule or add_rule as well when everything else was
(Ftr: You can add_rule when there is no rule yet afaik)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, that's the only issue I found, and it's not actually an issue, so I'll just merge this after doing some test gens so we can make RC3 as soon as possible
If you want to change it, it can be a followup PR ofc
worlds/osrs/Rules.py
Outdated
if skill.lower() == "fishing": | ||
return get_fishing_skill_rule(level, player, options) | ||
if skill.lower() == "mining": | ||
return get_mining_skill_rule(level, player, options) | ||
if skill.lower() == "woodcutting": | ||
return get_woodcutting_skill_rule(level, player, options) | ||
if skill.lower() == "smithing": | ||
return get_smithing_skill_rule(level, player, options) | ||
if skill.lower() == "crafting": | ||
return get_crafting_skill_rule(level, player, options) | ||
if skill.lower() == "cooking": | ||
return get_cooking_skill_rule(level, player, options) | ||
if skill.lower() == "runecraft": | ||
return get_runecraft_skill_rule(level, player, options) | ||
if skill.lower() == "magic": | ||
return get_magic_skill_rule(level, player, options) | ||
if skill.lower() == "firemaking": | ||
return get_firemaking_skill_rule(level, player, options) | ||
|
||
return lambda state: True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spacing is off
if skill.lower() == "fishing": | |
return get_fishing_skill_rule(level, player, options) | |
if skill.lower() == "mining": | |
return get_mining_skill_rule(level, player, options) | |
if skill.lower() == "woodcutting": | |
return get_woodcutting_skill_rule(level, player, options) | |
if skill.lower() == "smithing": | |
return get_smithing_skill_rule(level, player, options) | |
if skill.lower() == "crafting": | |
return get_crafting_skill_rule(level, player, options) | |
if skill.lower() == "cooking": | |
return get_cooking_skill_rule(level, player, options) | |
if skill.lower() == "runecraft": | |
return get_runecraft_skill_rule(level, player, options) | |
if skill.lower() == "magic": | |
return get_magic_skill_rule(level, player, options) | |
if skill.lower() == "firemaking": | |
return get_firemaking_skill_rule(level, player, options) | |
return lambda state: True | |
if skill.lower() == "fishing": | |
return get_fishing_skill_rule(level, player, options) | |
if skill.lower() == "mining": | |
return get_mining_skill_rule(level, player, options) | |
if skill.lower() == "woodcutting": | |
return get_woodcutting_skill_rule(level, player, options) | |
if skill.lower() == "smithing": | |
return get_smithing_skill_rule(level, player, options) | |
if skill.lower() == "crafting": | |
return get_crafting_skill_rule(level, player, options) | |
if skill.lower() == "cooking": | |
return get_cooking_skill_rule(level, player, options) | |
if skill.lower() == "runecraft": | |
return get_runecraft_skill_rule(level, player, options) | |
if skill.lower() == "magic": | |
return get_magic_skill_rule(level, player, options) | |
if skill.lower() == "firemaking": | |
return get_firemaking_skill_rule(level, player, options) | |
return lambda state: True |
|
||
if region_row.name == RegionNames.Lumbridge: | ||
# Canoe Tree access for the Location | ||
if outbound_region_name == RegionNames.Canoe_Tree: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe from here on you can start using if/elif again instead of if/if. I commented this earlier but I think it was missed
Getting loads of errors on a fully random yaml - Idk if this was always the case because random settings don't work well with this game because they end up being unsolvable / restrictive? I don't feel like it was ever this much though, like every 3rd or 4th fully random seed fails. Well, here are some seeds Ftr, these hit Fill errors, not one of your designated Exceptions (I hit that too a couple of times, but that's fine) Old School Runescape.json |
…multiple skills how actually check all skills
Mentioned it in DM's but just putting it here as well: Cook Some Stew has accessibility problems from Fishing |
def task_within_skill_levels(self, skills_required): | ||
# Loop through each required skill. If any of its requirements are out of the defined limit, return false | ||
for skill in skills_required: | ||
max_level_for_skill = getattr(self.options, f"max_{skill.skill.lower()}_level") | ||
if skill.level > max_level_for_skill: | ||
return False | ||
return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't actually need to do this, I'm doing this purely as an exercise for myself lol
So this could be...
return all(
skill.level <= getattr(self.options, f"max_{skill.skill.lower()}_level") for skill in skills_required
)
Hey that looks kinda nice, maybe you should do this instead LOL nah only if you want to
worlds/osrs/__init__.py
Outdated
def pre_fill(self) -> None: | ||
all_state = self.multiworld.get_all_state(False) | ||
for location in self.multiworld.get_locations(self.player): | ||
# if not location.can_reach(all_state): | ||
# options = self.options | ||
# print(f"{location} can't be reached even with every progression item.\n{all_state.prog_items[self.player]}") | ||
assert location.can_reach( | ||
all_state), f"{location} can't be reached even with every progression item.\n{all_state.prog_items[self.player]}" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice debugging tool, but I don't actually think it should be in main :D
95140043061228385161
Very rare, but this seems very fixable |
Still trying to work this out. As far as I can tell, the seed it builds is legitimately unbeatable. I just mapped out the items and locations available and it legitimately cannot place that last item anywhere it can actually be reached at. I think I'll need to find a way to check for this during Task generation and swap out tasks if it fails. |
I'm confused/concerned that it seems to only happen with multiple OSRS players. I did three thousand solo gens and didn't hit this at all, but hit it several times in just 100 2-player gens |
There's something strange going on here. I need to do some investigation. |
This is not your fault. It's a bug with Fill. |
There is still an unaddressed comment, otherwise I am good to merge this |
…en Regions are accessible (ArchipelagoMW#4188) * Removes explicit indirect conditions * Changes special rules function add rule instead of setting, and call it unconditionally * Fixes issues in rule generation that have been around but unused the whole time * Finally moves rules out into a separate file. Fixes level-related logic * Removes redundant max skill level checks on canoes, since they're in the skill training rules now * For some reason, canoe logic assumed you could always walk from lumbridge to south varrock without farms. This has been fixed * Apply suggestions from code review Co-authored-by: Exempt-Medic <[email protected]> * Quests now respect skill limits and can be excluded. Tasks that take multiple skills how actually check all skills * Adds alternative route for cooking that doesn't require fishing * Remove debug code --------- Co-authored-by: Exempt-Medic <[email protected]> Co-authored-by: NewSoupVi <[email protected]>
What is this fixing or adding?
Addresses issues found in RC testing - Regions that required a skill level to access (ex. Crafting Guild, Cooking Guild, and Canoe tasks) were not properly checking to make sure their requirements were within the Max Skill Level set in the options. This would mean that a player might need to reach 32 Cooking to access an Apple from the Cooking Guild for a Level 30 Cooking Task, even if 30 were the chosen max Cooking Level required.
Additionally, some general cleanup to make rules logic easier to work with, and to fix a few edge cases:
explicit_indirect_conditions = False
. If OSRS doesn't qualify for it, then nothing doesHow was this tested?
The easiest situation to force is the Canoe logic. By setting max woodcutting level to 1, we essentially remove the ability to use Canoes. 10 seeds were rolled, and all spoiler logs were checked for any logical paths that took any Canoe route, and none were found. 10 more seeds with a Woodcutting Level of 99 were rolled, and all of them contained at least one Canoe route.
Things like Crafting Guild and Cooking Guild access are more complicated to test since they require more than just a skill level to access, so those will need to be tested with actual runs.
Automated tests were also run multiple times to ensure the Indirect Condition removal did not cause any failures to generate. Indirect Condition related failures were quite rare though, so I cannot be 100% sure they're gone.