* fix(docker): Correct copy command to use recursive flag for EnemizerCLI
- Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory
* docs(deployment): Update container deployment documentation
- Specify minimum versions for Docker and Podman
- Add requirement for Docker Buildx plugin
* Sweep events per-player to reduce sweep iterations
By finding all accessible locations per player and then collecting the
items from those locations, if any collected items belong to a different
player, then that player may be able to access more locations the next
time all of their accessible locations are found. This reduces the
number of iterations necessary to sweep through and collect from all
accessible locations.
* Also sweep per-player in MultiWorld.can_beat_game
* Deduplicate code by using sweep_for_events in can_beat_game
sweep_for_events has been modified to be able to return a generator and
to be able to change the set of locations that are filtered out. This
way, the same code can be used by both functions.
* Skip checking locations by assuming each world only logically depends on itself
While this assumption almost always holds true, worlds are allowed to
logically depend on other worlds, so the sweep always double checks at
the end by checking the locations of every world before finishing.
* Fix missed update to CollectionState.collect implementation
Collecting items with prevent_sweep=True (previously event=True) no
longer always returns True, so the return value should now be checked.
* Comment and variable name consistency/clarity
accessible/inaccessible -> reachable/unreachable
final sweep iteration -> extra sweep iteration
maybe_final_sweep -> checking_if_finished
* Apply suggestions from code review
Use Iterator in return type hint instead of Iterable to help indicate that the returned value can only be iterated once.
Be consistent in return statements. Because sweep_for_events can return a value now, the conditional branch that has no intended return value should explicitly return None.
Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
* Update terminology from 'event' to 'advancement'
* Add typing overloads for sweep_for_advancements
This makes it so type-checkers and IDEs can see which calls return
`None` and which calls return `Iterator` so that it doesn't complain
about returning an `Iterator` from `sweep_for_events` or about iterating
through `None` in `can_beat_game`.
Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
* Update comment for why discard the player after finding their locations
A lack of clarity was brought up in review.
* Update for removed typing import
---------
Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
Since this does not have versions anymore, we check the sha256
and require manual intervention if it changed.
TODO: look for a way to do reproducible appimages again.
* chore(ci): exclude deployment and Docker files from unit test workflow triggers
- Modify unittests workflow to ignore changes in deploy directory and Docker-related files
* CreateHint command
* Docs
* oops
* forgot an arg
* Update MultiServer.py
* Add documentation on what happens when the hint already exists but with a different status (nothing)
* Early exit if no locations provided
* Add a clarifying comment to the code as well
* change wording a bit
* UPDATE: Dark Souls 3 setup docs to be more clear
* UPDATE: DS3 Setup docs to make offline mode more explicit
* UPDATE: Dark Souls 3 setup docs to be more clear
* UPDATE: DS3 Setup docs to make offline mode more explicit
* EDIT: DS3 setup docs to be up to date
Collecting an item into a CollectionState without sweeping, finding all
reachable locations, removing that item from the state, and then finding
all reachable locations again could result in more locations being
reachable than before the item was initially collected into the
CollectionState.
This issue was present because OoT was not invalidating its reachable
region caches for the different ages when items were removed from the
CollectionState.
To fix the issue, this PR has updated `OOTWorld.remove()` to invalid its
caches, like how `CollectionState.remove()` invalidates the core
Archipelago caches.
* fix(env): Prevent module update during requirements processing
- Add environment variable SKIP_REQUIREMENTS_UPDATE check
- Ensure update is skipped if SKIP_REQUIREMENTS_UPDATE is set to true
* squash! fix(env): Prevent module update during requirements processing - Add environment variable SKIP_REQUIREMENTS_UPDATE check - Ensure update is skipped if SKIP_REQUIREMENTS_UPDATE is set to true
* feat(docker): Add initial Docker configuration for project
- Add .dockerignore file to ignore unnecessary files
- Create Dockerfile with basic build and deployment configuration
* feat(docker): Updated Docker configuration for improved security and build efficiency
- Removed sensitive files from .dockerignore
- Moved WORKDIR to /app in Dockerfile
- Added gunicorn==23.0.0 dependency in RUN command
- Created new docker-compose.yml file for service definition
* feat(deployment): Implement containerized deployment configuration
- Add additional environment variables for Python optimization
- Update Dockerfile with new dependencies: eventlet, gevent, tornado
- Create docker-compose.yml and configure services for web and nginx
- Implement example configurations for web host settings and gunicorn
- Establish nginx configuration for reverse proxy
- Remove outdated docker-compose.yml from root directory
* feat(deploy): Introduce Docker Compose configuration for multi-world deployment
- Separate web service into two containers, one for main process and one for gunicorn
- Update container configurations for improved security and maintainability
- Remove unused volumes and network configurations
* docs: Add new documentation for deploying Archipelago using containers
- Document standalone image build and run process
- Include example Docker Compose file for container orchestration
- Provide information on services defined in the `docker-compose.yaml` file
- Mention optional Enemizer feature and Git requirements
* fixup! feat(docker): Updated Docker configuration for improved security and build efficiency - Removed sensitive files from .dockerignore - Moved WORKDIR to /app in Dockerfile - Added gunicorn==23.0.0 dependency in RUN command - Created new docker-compose.yml file for service definition
* feat(deploy): Updated gunicorn configuration example
- Adjusted worker and thread counts
- Switched worker class from sync to gthread
- Changed log level to info
- Added example code snippet for customizing worker count
* fix(deploy): Adjust concurrency settings for self-launch configuration
- Reduce the number of world generators from 8 to 3
- Decrease the number of hosters from 5 to 4
* docs(deploy using containers): Improve readability, fix broken links
- Update links to other documentation pages
- Improve formatting for better readability
- Remove unnecessary sections and files
- Add note about building the image requiring a local copy of ArchipelagoMW source code
* Update deploy/example_config.yaml
Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
* Update deploy/example_selflaunch.yaml
Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
* Update Dockerfile
Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
* Update deploy/example_selflaunch.yaml
Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
* fixup! Update Dockerfile
* fix(Dockerfile): Update package installations to use latest versions
- Remove specific version pins for git and libc6-dev
- Ensure compatibility with newer package updates
* feat(ci): Add GitHub Actions workflow for building and publishing Docker images
- Create a new workflow for Docker image build and publish
- Configure triggers for push and pull_request on main branch
- Set up QEMU and Docker Buildx for multi-platform builds
- Implement Docker login for GitHub Container Registry
- Include Docker image metadata extraction and tagging
* feat(healthcheck): Update Dockerfile and docker-compose for health checks
- Add health check for the Webhost service in Dockerfile
- Modify docker-compose to include a placeholder health check for multiworld service
- Standardize comments and remove unnecessary lines
* Revert "feat(ci): Add GitHub Actions workflow for building and publishing Docker images"
This reverts commit 32a51b272627d99ca9796cbfda2e821bfdd95c70.
* feat(docker): Enhance Dockerfile with Cython build stage
- Add Cython builder stage for compiling speedups
- Update package installation and organization for efficiency
- Improve caching by copying requirements before installing
- Add documentation for rootless Podman
* fixup! feat(docker): Enhance Dockerfile with Cython build stage - Add Cython builder stage for compiling speedups - Update package installation and organization for efficiency - Improve caching by copying requirements before installing - Add documentation for rootless Podman
---------
Co-authored-by: Adrian Priestley <apriestley@gmail.com>
Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
Co-authored-by: Adrian Priestley <apriestley@bob.localdomain>
* Options: forbid worlds just dumping every single option they don't need
* make the equal proper
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* update the id formatter to use staticmethods to not fake the unused self arg, and then use the formatter for the user session endpoints
* missed an id (ty treble)
* clean up duplicate code
* Update WebHostLib/__init__.py
Co-authored-by: Aaron Wagener <mmmcheese158@gmail.com>
* keep the BaseConverter format
* lol, change all the instances
* revert this
---------
Co-authored-by: Aaron Wagener <mmmcheese158@gmail.com>
* Add new deprioritized item flag
* 4 retries
* indent
* .
* style
* I think this is nicer
* Nicer
* remove two lines again that I added unnecessarily
* I think this test makes a bit more sense like this
* Idk how to word this lol
* Add progression_deprioritized_skip_balancing bc why not ig
* More text
* Update Fill.py
* Update Fill.py
* I am the big stupid
* Actually collect the other half of progression items into state when filling without them
* More clarity on the descriptions (hopefully)
* visually separate technical description and use cases
* Actually make the call do what the comments say it does
The previous swap_state can often be used as the base state to create
the next swap_state. This previous swap_state will already have
collected all items in item_pool and is likely to have checked many
locations, meaning that creating the next swap_state from it instead of
from base_state is faster.
From generating with extra code to raise an exception if more than 2
previous swap states were used, and using A Hat in Time and Pokemon
Red/Blue yamls that often result in lots of swapping in progression
fill, I could not get a single seed go through more than 2 previous swap
states. A few worlds' pre-fills do often use more than 2 previous swap
states, notably LADX which sometimes goes through over 20.
Given a 20 player Pokemon Red/Blue multiworld that usually generates in
around 16 or 17 seconds, but on a specific seed that results in 56
swaps, generation went from about 260 seconds before this patch to about
104 seconds after this patch (generated with a meta.yaml to disable
progression balancing and `python -O Generate.py --skip_output`).
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
Calling the dunder method has to:
1. Look up the dunder method for that object/class
2. Bind a new method instance to the object instance
3. Call the method with its arguments
4. Run the appropriate operation on the object
Whereas running the appropriate operation on the object from the start
skips straight to step 4.
Region.Register.__getitem__ is called a lot without #4583. In that case,
generation of 10 template Blasphemous yamls with
`--skip_output --seed 1` and progression balancing disabled went from
19.0s to 18.8s (1.3% reduction in generation duration).
From profiling with `timeit`
```py
def __getitem__(self, index: int) -> Location:
return self._list[index]
```
appears to be about twice as fast as the old code:
```py
def __getitem__(self, index: int) -> Location:
return self._list.__getitem__(index)
```
Besides this, there is not expected to be any noticeable difference in
performance, and there is not expected to be any difference in semantics
with these changes.
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>