Core: Add spoiler-only output mode (#4059)

* Core: Add spoiler-only output mode

* spoiler-only exceptions

* Move new errors to mystery_argparse
This commit is contained in:
Benjamin S Wolf
2025-04-05 06:50:52 -07:00
committed by GitHub
parent cd4da36863
commit ec75793ac3
3 changed files with 24 additions and 1 deletions

View File

@@ -54,12 +54,22 @@ def mystery_argparse():
parser.add_argument("--skip_output", action="store_true", parser.add_argument("--skip_output", action="store_true",
help="Skips generation assertion and output stages and skips multidata and spoiler output. " help="Skips generation assertion and output stages and skips multidata and spoiler output. "
"Intended for debugging and testing purposes.") "Intended for debugging and testing purposes.")
parser.add_argument("--spoiler_only", action="store_true",
help="Skips generation assertion and multidata, outputting only a spoiler log. "
"Intended for debugging and testing purposes.")
args = parser.parse_args() args = parser.parse_args()
if args.skip_output and args.spoiler_only:
parser.error("Cannot mix --skip_output and --spoiler_only")
elif args.spoiler == 0 and args.spoiler_only:
parser.error("Cannot use --spoiler_only when --spoiler=0. Use --skip_output or set --spoiler to a different value")
if not os.path.isabs(args.weights_file_path): if not os.path.isabs(args.weights_file_path):
args.weights_file_path = os.path.join(args.player_files_path, args.weights_file_path) args.weights_file_path = os.path.join(args.player_files_path, args.weights_file_path)
if not os.path.isabs(args.meta_file_path): if not os.path.isabs(args.meta_file_path):
args.meta_file_path = os.path.join(args.player_files_path, args.meta_file_path) args.meta_file_path = os.path.join(args.player_files_path, args.meta_file_path)
args.plando: PlandoOptions = PlandoOptions.from_option_string(args.plando) args.plando: PlandoOptions = PlandoOptions.from_option_string(args.plando)
return args return args
@@ -108,6 +118,8 @@ def main(args=None) -> Tuple[argparse.Namespace, int]:
raise Exception("Cannot mix --sameoptions with --meta") raise Exception("Cannot mix --sameoptions with --meta")
else: else:
meta_weights = None meta_weights = None
player_id = 1 player_id = 1
player_files = {} player_files = {}
for file in os.scandir(args.player_files_path): for file in os.scandir(args.player_files_path):
@@ -164,6 +176,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]:
erargs.outputpath = args.outputpath erargs.outputpath = args.outputpath
erargs.skip_prog_balancing = args.skip_prog_balancing erargs.skip_prog_balancing = args.skip_prog_balancing
erargs.skip_output = args.skip_output erargs.skip_output = args.skip_output
erargs.spoiler_only = args.spoiler_only
erargs.name = {} erargs.name = {}
erargs.csv_output = args.csv_output erargs.csv_output = args.csv_output

11
Main.py
View File

@@ -81,7 +81,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
del item_digits, location_digits, item_count, location_count del item_digits, location_digits, item_count, location_count
# This assertion method should not be necessary to run if we are not outputting any multidata. # This assertion method should not be necessary to run if we are not outputting any multidata.
if not args.skip_output: if not args.skip_output and not args.spoiler_only:
AutoWorld.call_stage(multiworld, "assert_generate") AutoWorld.call_stage(multiworld, "assert_generate")
AutoWorld.call_all(multiworld, "generate_early") AutoWorld.call_all(multiworld, "generate_early")
@@ -224,6 +224,15 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
logger.info(f'Beginning output...') logger.info(f'Beginning output...')
outfilebase = 'AP_' + multiworld.seed_name outfilebase = 'AP_' + multiworld.seed_name
if args.spoiler_only:
if args.spoiler > 1:
logger.info('Calculating playthrough.')
multiworld.spoiler.create_playthrough(create_paths=args.spoiler > 2)
multiworld.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase))
logger.info('Done. Skipped multidata modification. Total time: %s', time.perf_counter() - start)
return multiworld
output = tempfile.TemporaryDirectory() output = tempfile.TemporaryDirectory()
with output as temp_dir: with output as temp_dir:
output_players = [player for player in multiworld.player_ids if AutoWorld.World.generate_output.__code__ output_players = [player for player in multiworld.player_ids if AutoWorld.World.generate_output.__code__

View File

@@ -135,6 +135,7 @@ def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=Non
{"bosses", "items", "connections", "texts"})) {"bosses", "items", "connections", "texts"}))
erargs.skip_prog_balancing = False erargs.skip_prog_balancing = False
erargs.skip_output = False erargs.skip_output = False
erargs.spoiler_only = False
erargs.csv_output = False erargs.csv_output = False
name_counter = Counter() name_counter = Counter()