Stardew Valley: Properly support Universal Tracker (#3630)

* save the seed in slot data to reuse it in UT

* add logging when seed is missing

* add UT test and fix bundle test

* self review

* run UT test on allsanity+mod so it's more meaningfull
This commit is contained in:
Jérémie Bolduc
2024-07-26 05:33:14 -04:00
committed by GitHub
parent cc22161644
commit 9d36ad0df2
7 changed files with 105 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
import argparse
import json
from ...options import FarmType, EntranceRandomization
from ...test import setup_solo_multiworld, allsanity_mods_6_x_x
if __name__ == "__main__":
@@ -10,21 +11,23 @@ if __name__ == "__main__":
args = parser.parse_args()
seed = args.seed
multi_world = setup_solo_multiworld(
allsanity_mods_6_x_x(),
seed=seed
)
options = allsanity_mods_6_x_x()
options[FarmType.internal_name] = FarmType.option_standard
options[EntranceRandomization.internal_name] = EntranceRandomization.option_buildings
multi_world = setup_solo_multiworld(options, seed=seed)
world = multi_world.worlds[1]
output = {
"bundles": {
bundle_room.name: {
bundle.name: str(bundle.items)
for bundle in bundle_room.bundles
}
for bundle_room in multi_world.worlds[1].modified_bundles
for bundle_room in world.modified_bundles
},
"items": [item.name for item in multi_world.get_items()],
"location_rules": {location.name: repr(location.access_rule) for location in multi_world.get_locations(1)}
"location_rules": {location.name: repr(location.access_rule) for location in multi_world.get_locations(1)},
"slot_data": world.fill_slot_data()
}
print(json.dumps(output))

View File

@@ -24,8 +24,7 @@ class TestGenerationIsStable(SVTestCase):
if self.skip_long_tests:
raise unittest.SkipTest("Long tests disabled")
# seed = get_seed(33778671150797368040) # troubleshooting seed
seed = get_seed(74716545478307145559)
seed = get_seed()
output_a = subprocess.check_output([sys.executable, '-m', 'worlds.stardew_valley.test.stability.StabilityOutputScript', '--seed', str(seed)])
output_b = subprocess.check_output([sys.executable, '-m', 'worlds.stardew_valley.test.stability.StabilityOutputScript', '--seed', str(seed)])
@@ -54,3 +53,6 @@ class TestGenerationIsStable(SVTestCase):
# We check that the actual rule has the same order to make sure it is evaluated in the same order,
# so performance tests are repeatable as much as possible.
self.assertEqual(rule_a, rule_b, f"Location rule of {location_a} at index {i} is different between both executions. Seed={seed}")
for key, value in result_a["slot_data"].items():
self.assertEqual(value, result_b["slot_data"][key], f"Slot data {key} is different between both executions. Seed={seed}")

View File

@@ -0,0 +1,52 @@
import unittest
from unittest.mock import Mock
from .. import SVTestBase, create_args, allsanity_mods_6_x_x
from ... import STARDEW_VALLEY, FarmType, BundleRandomization, EntranceRandomization
class TestUniversalTrackerGenerationIsStable(SVTestBase):
options = allsanity_mods_6_x_x()
options.update({
EntranceRandomization.internal_name: EntranceRandomization.option_buildings,
BundleRandomization.internal_name: BundleRandomization.option_shuffled,
FarmType.internal_name: FarmType.option_standard, # Need to choose one otherwise it's random
})
def test_all_locations_and_items_are_the_same_between_two_generations(self):
# This might open a kivy window temporarily, but it's the only way to test this...
if self.skip_long_tests:
raise unittest.SkipTest("Long tests disabled")
try:
# This test only run if UT is present, so no risk of running in the CI.
from worlds.tracker.TrackerClient import TrackerGameContext # noqa
except ImportError:
raise unittest.SkipTest("UT not loaded, skipping test")
slot_data = self.world.fill_slot_data()
ut_data = self.world.interpret_slot_data(slot_data)
fake_context = Mock()
fake_context.re_gen_passthrough = {STARDEW_VALLEY: ut_data}
args = create_args({0: self.options})
args.outputpath = None
args.outputname = None
args.multi = 1
args.race = None
args.plando_options = self.multiworld.plando_options
args.plando_items = self.multiworld.plando_items
args.plando_texts = self.multiworld.plando_texts
args.plando_connections = self.multiworld.plando_connections
args.game = self.multiworld.game
args.name = self.multiworld.player_name
args.sprite = {}
args.sprite_pool = {}
args.skip_output = True
generated_multi_world = TrackerGameContext.TMain(fake_context, args, self.multiworld.seed)
generated_slot_data = generated_multi_world.worlds[1].fill_slot_data()
# Just checking slot data should prove that UT generates the same result as AP generation.
self.maxDiff = None
self.assertEqual(slot_data, generated_slot_data)