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

lufia2ac: coop support #1868

Merged
merged 4 commits into from
Jun 29, 2023
Merged

lufia2ac: coop support #1868

merged 4 commits into from
Jun 29, 2023

Conversation

el-u
Copy link
Collaborator

@el-u el-u commented Jun 14, 2023

What is this fixing or adding?

  • lufia2ac: coop support
    This adds multiworld coop support to the Lufia II Ancient Cave world.
    The coop aspect applies both to opening blue chests to send out checks as well as to the collection of items for the Iris treasure hunt goals.

    • Blue chests opened by anyone connected to the coop slot will be added together, e.g., if personA has opened 3 blue chests while personB has opened 4 blue chests, then a total of 7 location checks will have been sent out from this slot.
    • Regarding the local Iris treasures, if, e.g., personA finds the Iris sword and Iris ring while personB finds the Iris armor, then all 3 of these Iris items will be counted towards the shared goal.
  • Core: update version to 0.4.2
    This is required because the new feature can only be realized using a new version of the game client

  • CommonClient: add a framework for clients to subscribe to data storage key notifications
    Adds a new method set_notify to CommonContext. Using this method, a game client can subscribe to be notified of changes to selected data storage keys. The values of interest can be accessed via the new stored_data attribute of the context. It is a dictionary mapping the names of the data storage keys to their values. This dict is automatically kept up to date whenever the server sends out a packet containing the value of one of the subscribed keys.

    This framework is used to implement the new feature in the client of Lufia II. In principle it should be possible to rewrite FactorioClients usage of the "EnergyLink" key to use this new generic mechanism, but I did not attempt this since I don't play Factorio and wouldn't be able to test it.

  • Core: typing for async_start
    This PR also contains a correction to the type hints of the async_start method (which is used by the framework described above). The existing type hints only supported bool return values, even though there are already various existing uses with other return types (mostly None). Also, it permitted arbitrary yield and send types, even though these features don't seem to be usable through async_start.

How was this tested?

https://discord.com/channels/731205301247803413/1112481808160923761
https://discord.com/channels/731205301247803413/1116393188702306424

@ThePhar ThePhar added is: enhancement Issues requesting new features or pull requests implementing new features. affects: core Issues/PRs that touch core and may need additional validation. labels Jun 19, 2023
@el-u
Copy link
Collaborator Author

el-u commented Jun 25, 2023

Which problem is this PR trying to solve?

The main challenge concerning blue chest coop is that since everything in game is randomly generated we do not have an individual ID for each blue chest. Instead, we can only keep track of how many blue chests have been opened. But on AP's side, each check will need to have its own location ID. To deal with this, the client previously reported the blue chest checks in sequence, the first chest opened (no matter where in game it appeared) being reported as the location "Blue chest 1", the next one always as "Blue chest 2", etc., going up to the number of how many chests have been opened.

This works fine for a single person playing, but if two people are on the same slot, their clients will only report up to the number of checks opened by that individual, meaning that the contributions of multiple persons will not be added together and some of their efforts will be wasted. (Essentially, only the single contribution with the most chests would count. E.g., if one client reported 3 blue chests while another one reported 4, then the total number of locations checked as far as AP is concerned would still only be 4, even though a total of 7 chests have been found by the two people.)

How does the solution work?

To solve this problem and add support for true coop, this PR makes use of data storage. For each lufia2ac world there is a single data storage key, whose value will itself be a dict, mapping a unique ID for each save file to the number of blue chests opened on that save. The client reads that ID from the file; if no valid existing ID is found (i.e., on the first run), a new randomly generated one will be written to the save, thus making them distinguishable.

As before, each game keeps track of how many chests have been checked on that file, but now (instead of sending location checks directly) each client keeps modifying the data storage by sending that number as an update for the subkey corresponding to its own save file ID. At the same time, each client will also subscribe to that key and receive it from the server in full (including the data supplied from other clients/save files). Clients then add up all these reported chest counts and send out a corresponding number of total locations checks, thus ensuring that everyone's efforts are combined.

Aside from blue chests, this PR also makes changes to the items required for goal completion (namely the 9 Iris treasures and the Ancient key). Previously, these were handled entirely within the game itself and not even reported to the server as checks. Since each of them can already be identified via their item ID, the only thing required to make goal completion coop-able was to turn these items into proper (Archipelago) items and to enable the game to send and receive them.



def async_start(co: Coroutine[typing.Any, typing.Any, bool], name: Optional[str] = None) -> None:
def async_start(co: Coroutine[None, None, typing.Any], name: Optional[str] = None) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks like good typing around this function.

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.

I checked everything that is not CommonClient.py or Client.py. Hoping @Berserker66 will find the time to do that

Copy link
Member

@Berserker66 Berserker66 left a comment

Choose a reason for hiding this comment

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

Looked at Client.py and CommonClient.py
Wondering if the := syntax will result in people asking what it is on discord, as it's so rarely used, might even be the first time in AP.

@el-u
Copy link
Collaborator Author

el-u commented Jun 29, 2023

Thanks

Wondering if the := syntax will result in people asking what it is on discord, as it's so rarely used, might even be the first time in AP.

Using Python 3.8 features in AP is basically bleeding edge. ^^
Not the first time, though; I've used it before.

Utils.py Show resolved Hide resolved
@ThePhar ThePhar merged commit dfb3df4 into ArchipelagoMW:main Jun 29, 2023
@el-u el-u deleted the lufia2ac-main branch June 29, 2023 21:51
FlySniper pushed a commit to FlySniper/Archipelago that referenced this pull request Nov 14, 2023
…goMW#1868)

* Core: typing for async_start

* CommonClient: add a framework for clients to subscribe to data storage key notifications

* Core: update version to 0.4.2

* lufia2ac: coop support
Jouramie pushed a commit to Jouramie/Archipelago that referenced this pull request Feb 28, 2024
…goMW#1868)

* Core: typing for async_start

* CommonClient: add a framework for clients to subscribe to data storage key notifications

* Core: update version to 0.4.2

* lufia2ac: coop support
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. is: enhancement Issues requesting new features or pull requests implementing new features.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants