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

Docs: Dev FAQ - About indirect conditions #3698

Closed
wants to merge 19 commits into from
Closed
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/apworld_dev_faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,26 @@ A faster alternative to the `for` loop would be to use a [list comprehension](ht
```py
item_pool += [self.create_filler() for _ in range(total_locations - len(item_pool))]
```

---

### I learned about indirect conditions in the world API document, but I want to know more. What are they and why are they necessary?

The world API document mentions indirect conditions and **when** you should use them, but not *how* they work and *why* they are necessary. This is because the explanation is quite complicated.

Region sweep (the algorithm that determines which regions are reachable) is a Breadth First Search of the region graph from the Menu region, checking entrances one by one and adding newly reached nodes (regions) and their entrances to the queue until there is nothing more to check.
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved

However, if entrance access conditions depend on regions, then it is possible for this to happen:
1. An entrance that depends on a region is checked and determined to be untraversable because the region hasn't been reached yet during the graph search.
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved
2. After that, the region is reached by the graph search. The entrance *would* now be determined to be traversable if it were rechecked.
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved

To account for this case, we would have to recheck all entrances every time a new region is reached, until no new regions are reached.

Because most games do not check for region access inside of entrance access conditions, AP has decided to **eschew this rechecking** and just checks every entrance once. This gives a significant performance gain to AP as a whole, about 30%-50%.

However, because some games *did* start using things like `region.can_reach` inside entrance access conditions, we provided a way to **manually** define that a *specific* entrance needs to be rechecked during region sweep if a *specific* region is reached during it. This is what an indirect condition is.
This keeps almost all of the performance upsides. Even a game making heavy use of indirect conditions (See: The Witness) is still way way faster than if it just blanket "rechecked all entrances until nothing new is found".
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

It seems weird ro say "the performance upsides" when they aren't mentioned anywhere. I think some of the structure/paragraphing here jumps around from topic quickly in ways thar carry assumptions about the dev's knowing why the subject is changing. I don't think how it is now is particularly bad but I'd have to think a good bit to come up with a structure I think would be better

Copy link
Member Author

Choose a reason for hiding this comment

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

There is "For performance reasons, ..." some paragraphs before this
Might not be direct enough, idk

The reason entrance access rules using `location.can_reach` and `entrance.can_reach` are also affected is simple: They call `region.can_reach` on their respective parent/source region.
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved

We recognize it's a pretty bad beginner's trap (heck, not even a "beginner's" trap, just a trap - even for experienced AP devs), and some games are very complex with their access rules.
NewSoupVi marked this conversation as resolved.
Show resolved Hide resolved
There is an open Pull Request that makes this behavior optional via a world class attribute: [Core: Region handling customization](https://github.com/ArchipelagoMW/Archipelago/pull/3682).