Skip to content

Conversation

@theballaam96
Copy link
Collaborator

No description provided.

UmedMuzl and others added 30 commits January 11, 2026 21:42
- Fixed a bug where the fake fairy song wouldn't end when going out of range of an ice trap fairy
- Fixed a bug where talking to vanilla caged Diddy without pressing B to close the textbox would softlock you. (technically, you're now forced to press B to close the textbox, or it won't close)
- Fixed a bug where music would always be sped up when playing with certain win conditions without requiring K.Rool.
world.options.logic_type.value = 1 # Force to glitchless

if affected_players:
import logging

Check notice

Code scanning / CodeQL

Module is imported more than once Note

This import of module logging is redundant, as it was previously imported
on line 135
.

Copilot Autofix

AI 8 days ago

To fix the issue, remove the redundant inner import logging and rely on the existing top-level import logging at line 135. In general, modules should be imported once at module scope unless there is a specific need for a local or conditional import.

Concretely, in __init__.py, within the generate_early method around lines 968–974, delete the line import logging that appears just before logging.warning(...). No other changes are necessary: the logging.warning call will use the module imported at line 135. This preserves all existing behavior while cleaning up the redundant import.

Suggested changeset 1
__init__.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/__init__.py b/__init__.py
--- a/__init__.py
+++ b/__init__.py
@@ -966,8 +966,6 @@
                         world.options.logic_type.value = 1  # Force to glitchless
 
                 if affected_players:
-                    import logging
-
                     logging.warning(
                         f"DK64: Minimal logic is DISABLED in host.yaml. "
                         f"The following player(s) have tried to sneak Minimal Logic in: {', '.join(affected_players)}. As such, they have been forced to use glitchless logic."
EOF
@@ -966,8 +966,6 @@
world.options.logic_type.value = 1 # Force to glitchless

if affected_players:
import logging

logging.warning(
f"DK64: Minimal logic is DISABLED in host.yaml. "
f"The following player(s) have tried to sneak Minimal Logic in: {', '.join(affected_players)}. As such, they have been forced to use glitchless logic."
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
try:
ap_location = world.get_location(location_data.name, player)
forbid_item(ap_location, "Donkey", player)
except KeyError:

Check notice

Code scanning / CodeQL

Empty except Note

'except' clause does nothing but pass and there is no explanatory comment.

Copilot Autofix

AI 8 days ago

In general, to fix an empty except block, either (a) add appropriate handling such as logging, cleanup, or re-raising, or (b) add a clear explanatory comment if intentional and benign. Here we can improve safety and diagnosability without changing functional behavior by logging the issue and then skipping the problematic location, matching the intent of “ignore if missing.” The earlier use site in the same function (lines 68–71) already uses continue to skip nonexistent locations, so we should mirror that explicit behavior.

Concretely, in archipelago/Rules.py, within apply_minimal_logic_rules, replace the except KeyError: pass block at lines 108–112 with a block that documents the intent and continues the loop (or simply returns to the next iteration), and optionally logs a debug message. To avoid new dependencies and minimize external assumptions, we can rely on the standard logging module, which is well-known and widely used. We will add a logging import and a module-level logger. Then, in the except KeyError: block, we log a debug message indicating the location was not found and then continue to the next loc_id in non_dk_location_ids. This preserves the current behavior of “do not crash if the location is missing,” but no longer has a completely empty handler.

Suggested changeset 1
archipelago/Rules.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/archipelago/Rules.py b/archipelago/Rules.py
--- a/archipelago/Rules.py
+++ b/archipelago/Rules.py
@@ -8,8 +8,11 @@
 from randomizer.Enums.Maps import Maps
 from randomizer.Enums.Types import Types
 from randomizer.Enums.Settings import ShuffleLoadingZones, LogicType
+import logging
 
+logger = logging.getLogger(__name__)
 
+
 def set_rules(world: MultiWorld, player: int):
     """Set the rules for the given player's world."""
     world.completion_condition[player] = lambda state: state.has("Banana Hoard", player)
@@ -109,4 +110,11 @@
                 ap_location = world.get_location(location_data.name, player)
                 forbid_item(ap_location, "Donkey", player)
             except KeyError:
-                pass
+                # Location does not exist in Archipelago for this player; skip applying this rule.
+                logger.debug(
+                    "Non-DK location '%s' (id %s) not found in world for player %s; skipping DK restriction.",
+                    location_data.name,
+                    loc_id,
+                    player,
+                )
+                continue
EOF
@@ -8,8 +8,11 @@
from randomizer.Enums.Maps import Maps
from randomizer.Enums.Types import Types
from randomizer.Enums.Settings import ShuffleLoadingZones, LogicType
import logging

logger = logging.getLogger(__name__)


def set_rules(world: MultiWorld, player: int):
"""Set the rules for the given player's world."""
world.completion_condition[player] = lambda state: state.has("Banana Hoard", player)
@@ -109,4 +110,11 @@
ap_location = world.get_location(location_data.name, player)
forbid_item(ap_location, "Donkey", player)
except KeyError:
pass
# Location does not exist in Archipelago for this player; skip applying this rule.
logger.debug(
"Non-DK location '%s' (id %s) not found in world for player %s; skipping DK restriction.",
location_data.name,
loc_id,
player,
)
continue
Copilot is powered by AI and may make mistakes. Always verify output.
# we still need to add them to item_assignment for patching purposes
if Types.Key not in spoiler.settings.shuffled_location_types:
if spoiler.settings.shuffle_loading_zones == ShuffleLoadingZones.levels:
import randomizer.ItemPool as ItemPool

Check notice

Code scanning / CodeQL

Cyclic import Note

Import of module
randomizer.ItemPool
begins an import cycle.

Copilot Autofix

AI 8 days ago

In general, to fix this kind of cyclic import you remove the direct import that participates in the cycle and instead depend on something that does not itself depend back on the current module. Typical approaches include: moving the shared functionality to a third, lower‑level module; inlining very small helper logic; or passing required objects as arguments instead of importing them.

Here, ShuffleItems only needs ItemPool.Keys() to obtain the collection of key items. We can break the cycle without changing behavior by locally defining the same Keys() logic in this file (or, equivalently, by inlining the check) instead of importing ItemPool. Since we must not modify other files, the best option within this snippet is to remove the import randomizer.ItemPool as ItemPool in the conditional block and replace its usage with a small helper function that returns the key items. To avoid assumptions about the rest of the code, we can implement Keys() using the already‑imported Items enum, which is the natural place where the key items live.

Concretely:

  • Add a new helper function near the top of ShuffleItems.py, e.g. def _key_items(): ..., returning the same iterable that ItemPool.Keys() would have provided. This uses Items values that correspond to keys (e.g., Items.Key1Items.Key8 or whatever subset is applicable).
  • Replace the local import import randomizer.ItemPool as ItemPool with a call to this helper, i.e., call _key_items() instead of ItemPool.Keys().
  • Adjust the if condition in the loop over LevelInfoList.values() to check membership in _key_items() instead of ItemPool.Keys(). No other behavior changes are needed.

This eliminates the cycle by removing ShuffleItems’s dependency on ItemPool while preserving the semantics of “is this item a key?” as long as the helper returns the correct set of key Items values.

Suggested changeset 1
randomizer/ShuffleItems.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/randomizer/ShuffleItems.py b/randomizer/ShuffleItems.py
--- a/randomizer/ShuffleItems.py
+++ b/randomizer/ShuffleItems.py
@@ -14,6 +14,25 @@
 from randomizer.Patching.Library.ItemRando import LocationSelection
 
 
+def _key_items():
+    """Return the collection of key items used for vanilla key placement.
+
+    This mirrors the behavior of ItemPool.Keys() without importing ItemPool,
+    in order to avoid an import cycle.
+    """
+    # NOTE: Adjust this list if additional key items are introduced in Items.
+    return {
+        Items.Key1,
+        Items.Key2,
+        Items.Key3,
+        Items.Key4,
+        Items.Key5,
+        Items.Key6,
+        Items.Key7,
+        Items.Key8,
+    }
+
+
 class MoveData:
     """Class which contains information pertaining to a move's attributes."""
 
@@ -191,13 +210,12 @@
     # we still need to add them to item_assignment for patching purposes
     if Types.Key not in spoiler.settings.shuffled_location_types:
         if spoiler.settings.shuffle_loading_zones == ShuffleLoadingZones.levels:
-            import randomizer.ItemPool as ItemPool
 
             vanilla_keys_assignment = []
             for level in LevelInfoList.values():
                 key_location = spoiler.LocationList[level.KeyLocation]
 
-                if key_location.item is not None and key_location.item in ItemPool.Keys():
+                if key_location.item is not None and key_location.item in _key_items():
                     placement_info = {}
                     if key_location.default_mapid_data:
                         for location in key_location.default_mapid_data:
EOF
@@ -14,6 +14,25 @@
from randomizer.Patching.Library.ItemRando import LocationSelection


def _key_items():
"""Return the collection of key items used for vanilla key placement.

This mirrors the behavior of ItemPool.Keys() without importing ItemPool,
in order to avoid an import cycle.
"""
# NOTE: Adjust this list if additional key items are introduced in Items.
return {
Items.Key1,
Items.Key2,
Items.Key3,
Items.Key4,
Items.Key5,
Items.Key6,
Items.Key7,
Items.Key8,
}


class MoveData:
"""Class which contains information pertaining to a move's attributes."""

@@ -191,13 +210,12 @@
# we still need to add them to item_assignment for patching purposes
if Types.Key not in spoiler.settings.shuffled_location_types:
if spoiler.settings.shuffle_loading_zones == ShuffleLoadingZones.levels:
import randomizer.ItemPool as ItemPool

vanilla_keys_assignment = []
for level in LevelInfoList.values():
key_location = spoiler.LocationList[level.KeyLocation]

if key_location.item is not None and key_location.item in ItemPool.Keys():
if key_location.item is not None and key_location.item in _key_items():
placement_info = {}
if key_location.default_mapid_data:
for location in key_location.default_mapid_data:
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants